summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/Makefile29
-rw-r--r--src/mesa/SConscript33
-rw-r--r--src/mesa/drivers/dri/Makefile.template9
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c13
-rw-r--r--src/mesa/drivers/dri/common/dri_util.h5
-rw-r--r--src/mesa/drivers/dri/i915/i830_context.c1
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c61
-rw-r--r--src/mesa/drivers/dri/i965/Makefile5
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c9
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h26
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_disasm.c80
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.h10
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c63
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp1924
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp365
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp391
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_optimize.c81
-rw-r--r--src/mesa/drivers/dri/i965/brw_program.c36
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_structs.h11
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c134
-rw-r--r--src/mesa/drivers/dri/i965/brw_vtbl.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c27
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h21
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_debug.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c138
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c11
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c26
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_iz.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass0.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass1.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass2.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c18
-rw-r--r--src/mesa/drivers/dri/i965/gen6_cc.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen6_wm_state.c71
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c6
-rw-r--r--src/mesa/drivers/dri/intel/intel_chipset.h4
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c5
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h14
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c18
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.c67
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.h7
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c73
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.h2
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_driver.c2
-rw-r--r--src/mesa/drivers/dri/nouveau/nouveau_fbo.c2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/Makefile1
-rwxr-xr-xsrc/mesa/drivers/dri/r300/compiler/SConscript1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c18
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c231
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_code.h2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_compiler.h5
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c31
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c17
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h6
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c30
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c117
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c8
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c128
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.h36
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_common.c1
-rw-r--r--src/mesa/drivers/dri/r600/Makefile9
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_chip.c1289
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_chip.h516
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_context.c106
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_context.h (renamed from src/mesa/slang/slang_link.h)25
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_diff.h335
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_fragprog.c817
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_fragprog.h77
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_ioctl.c (renamed from src/mesa/slang/slang_emit.h)50
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_ioctl.h (renamed from src/mesa/slang/slang_mem.h)45
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_off.h881
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_oglprog.c193
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_oglprog.h (renamed from src/mesa/slang/library/slang_builtin_120_fragment.gc)21
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_render.c937
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_sq.h735
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_state.c1878
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_state.h47
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_tex.c1551
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_tex.h (renamed from src/mesa/slang/slang_log.h)51
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_vertprog.c736
-rw-r--r--src/mesa/drivers/dri/r600/evergreen_vertprog.h109
-rw-r--r--src/mesa/drivers/dri/r600/r600_blit.c9
-rw-r--r--src/mesa/drivers/dri/r600/r600_cmdbuf.c9
-rw-r--r--src/mesa/drivers/dri/r600/r600_cmdbuf.h40
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.c89
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.h50
-rw-r--r--src/mesa/drivers/dri/r600/r600_emit.c65
-rw-r--r--src/mesa/drivers/dri/r600/r600_emit.h10
-rw-r--r--src/mesa/drivers/dri/r600/r600_texstate.c26
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.c1700
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.h31
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.c135
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.h7
-rw-r--r--src/mesa/drivers/dri/r600/r700_fragprog.c33
-rw-r--r--src/mesa/drivers/dri/r600/r700_fragprog.h5
-rw-r--r--src/mesa/drivers/dri/r600/r700_oglprog.c21
-rw-r--r--src/mesa/drivers/dri/r600/r700_render.c1
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.c16
-rw-r--r--src/mesa/drivers/dri/r600/r700_vertprog.c55
-rw-r--r--src/mesa/drivers/dri/r600/r700_vertprog.h5
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_chipset.h45
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.c5
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c57
-rw-r--r--src/mesa/drivers/glslcompiler/Makefile43
-rw-r--r--src/mesa/drivers/glslcompiler/glslcompiler.c436
-rw-r--r--src/mesa/drivers/osmesa/Makefile7
-rw-r--r--src/mesa/drivers/x11/Makefile5
-rw-r--r--src/mesa/main/accum.h2
-rw-r--r--src/mesa/main/attrib.h2
-rw-r--r--src/mesa/main/bufferobj.c22
-rw-r--r--src/mesa/main/colortab.h2
-rw-r--r--src/mesa/main/compiler.h5
-rw-r--r--src/mesa/main/context.c31
-rw-r--r--src/mesa/main/convolve.h2
-rw-r--r--src/mesa/main/core.h66
-rw-r--r--src/mesa/main/dd.h51
-rw-r--r--src/mesa/main/depthstencil.c4
-rw-r--r--src/mesa/main/dlist.c10
-rw-r--r--src/mesa/main/dlist.h2
-rw-r--r--src/mesa/main/es_generator.py10
-rw-r--r--src/mesa/main/extensions.c2
-rw-r--r--src/mesa/main/fbobject.c2
-rw-r--r--src/mesa/main/feedback.h2
-rw-r--r--src/mesa/main/formats.c12
-rw-r--r--src/mesa/main/formats.h3
-rw-r--r--src/mesa/main/framebuffer.c4
-rw-r--r--src/mesa/main/get.c18
-rw-r--r--src/mesa/main/getstring.c4
-rw-r--r--src/mesa/main/imports.h52
-rw-r--r--src/mesa/main/mipmap.c17
-rw-r--r--src/mesa/main/mtypes.h56
-rw-r--r--src/mesa/main/querymatrix.c3
-rw-r--r--src/mesa/main/shaderapi.c12
-rw-r--r--src/mesa/main/shaderobj.c60
-rw-r--r--src/mesa/main/shaderobj.h29
-rw-r--r--src/mesa/main/shared.c4
-rw-r--r--src/mesa/main/texcompress_s3tc.c1
-rw-r--r--src/mesa/main/transformfeedback.c7
-rw-r--r--src/mesa/main/uniforms.c108
-rw-r--r--src/mesa/main/uniforms.h15
-rw-r--r--src/mesa/program/hash_table.c31
-rw-r--r--src/mesa/program/hash_table.h35
-rw-r--r--src/mesa/program/ir_to_mesa.cpp2796
-rw-r--r--src/mesa/program/ir_to_mesa.h38
-rw-r--r--src/mesa/program/prog_execute.c29
-rw-r--r--src/mesa/program/prog_instruction.h2
-rw-r--r--src/mesa/program/prog_optimize.c84
-rw-r--r--src/mesa/program/prog_parameter.c96
-rw-r--r--src/mesa/program/prog_parameter.h16
-rw-r--r--src/mesa/program/prog_print.c38
-rw-r--r--src/mesa/program/prog_print.h7
-rw-r--r--src/mesa/program/prog_uniform.c4
-rw-r--r--src/mesa/program/prog_uniform.h5
-rw-r--r--src/mesa/program/symbol_table.c59
-rw-r--r--src/mesa/program/symbol_table.h3
-rw-r--r--src/mesa/slang/descrip.mms67
-rw-r--r--src/mesa/slang/library/.gitignore1
-rw-r--r--src/mesa/slang/library/Makefile54
-rw-r--r--src/mesa/slang/library/SConscript62
-rw-r--r--src/mesa/slang/library/slang_120_core.gc1978
-rw-r--r--src/mesa/slang/library/slang_builtin_120_common.gc200
-rw-r--r--src/mesa/slang/library/slang_common_builtin.gc1887
-rw-r--r--src/mesa/slang/library/slang_core.gc2619
-rw-r--r--src/mesa/slang/library/slang_fragment_builtin.gc299
-rw-r--r--src/mesa/slang/library/slang_geometry_builtin.gc55
-rw-r--r--src/mesa/slang/library/slang_vertex_builtin.gc210
-rw-r--r--src/mesa/slang/slang_builtin.c1018
-rw-r--r--src/mesa/slang/slang_builtin.h68
-rw-r--r--src/mesa/slang/slang_codegen.c5410
-rw-r--r--src/mesa/slang/slang_codegen.h77
-rw-r--r--src/mesa/slang/slang_compile.c3103
-rw-r--r--src/mesa/slang/slang_compile.h103
-rw-r--r--src/mesa/slang/slang_compile_function.c262
-rw-r--r--src/mesa/slang/slang_compile_function.h100
-rw-r--r--src/mesa/slang/slang_compile_operation.c334
-rw-r--r--src/mesa/slang/slang_compile_operation.h229
-rw-r--r--src/mesa/slang/slang_compile_struct.c174
-rw-r--r--src/mesa/slang/slang_compile_struct.h69
-rw-r--r--src/mesa/slang/slang_compile_variable.c247
-rw-r--r--src/mesa/slang/slang_compile_variable.h92
-rw-r--r--src/mesa/slang/slang_emit.c2686
-rw-r--r--src/mesa/slang/slang_ir.c534
-rw-r--r--src/mesa/slang/slang_ir.h293
-rw-r--r--src/mesa/slang/slang_label.c106
-rw-r--r--src/mesa/slang/slang_label.h44
-rw-r--r--src/mesa/slang/slang_link.c1287
-rw-r--r--src/mesa/slang/slang_log.c133
-rw-r--r--src/mesa/slang/slang_mem.c243
-rw-r--r--src/mesa/slang/slang_print.c883
-rw-r--r--src/mesa/slang/slang_print.h35
-rw-r--r--src/mesa/slang/slang_simplify.c527
-rw-r--r--src/mesa/slang/slang_simplify.h57
-rw-r--r--src/mesa/slang/slang_storage.c321
-rw-r--r--src/mesa/slang/slang_storage.h139
-rw-r--r--src/mesa/slang/slang_typeinfo.c1177
-rw-r--r--src/mesa/slang/slang_typeinfo.h265
-rw-r--r--src/mesa/slang/slang_utility.c228
-rw-r--r--src/mesa/slang/slang_utility.h102
-rw-r--r--src/mesa/slang/slang_vartable.c362
-rw-r--r--src/mesa/slang/slang_vartable.h45
-rw-r--r--src/mesa/sources.mak40
-rw-r--r--src/mesa/state_tracker/st_cb_accum.h2
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c30
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c47
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c44
-rw-r--r--src/mesa/state_tracker/st_cb_eglimage.c3
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c28
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h5
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c31
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c14
-rw-r--r--src/mesa/state_tracker/st_context.c5
-rw-r--r--src/mesa/state_tracker/st_context.h3
-rw-r--r--src/mesa/state_tracker/st_draw.c3
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c45
-rw-r--r--src/mesa/state_tracker/st_extensions.c7
-rw-r--r--src/mesa/state_tracker/st_format.c5
-rw-r--r--src/mesa/state_tracker/st_manager.c31
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c3
-rw-r--r--src/mesa/state_tracker/st_program.c8
-rw-r--r--src/mesa/state_tracker/st_texture.c2
-rw-r--r--src/mesa/swrast/s_context.c2
-rw-r--r--src/mesa/vbo/vbo_exec_array.c4
-rw-r--r--src/mesa/x86/3dnow.h2
-rw-r--r--src/mesa/x86/common_x86.c49
-rw-r--r--src/mesa/x86/mmx.h3
-rw-r--r--src/mesa/x86/sse.h2
-rw-r--r--src/mesa/x86/x86_xform.c37
240 files changed, 20384 insertions, 29941 deletions
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 7073c92240b..ef31fd24f08 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -42,35 +42,53 @@ MESA_GALLIUM_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_GALLIUM_OBJECTS))
MESA_INCLUDES := $(INCLUDE_DIRS)
ES1_INCLUDES := -I$(TOP)/src/mapi/es1api $(INCLUDE_DIRS)
ES2_INCLUDES := -I$(TOP)/src/mapi/es2api $(INCLUDE_DIRS)
-
+MESA_INCLUDES := -I$(TOP)/src/glsl $(MESA_INCLUDES)
+ES1_INCLUDES := -I$(TOP)/src/glsl $(ES1_INCLUDES)
+ES2_INCLUDES := -I$(TOP)/src/glsl $(ES2_INCLUDES)
+# For symbol_table.h in glsl compiler headers.
+MESA_INCLUDES := -I$(TOP)/src/mesa/shader $(MESA_INCLUDES)
define mesa-cc-c
@mkdir -p $(dir $@)
$(CC) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_INCLUDES) $(CFLAGS)
endef
+define mesa-cxx-c
+ @mkdir -p $(dir $@)
+ $(CXX) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_INCLUDES) $(CXXFLAGS)
+endef
+
$(MESA_OBJ_DIR)/%.o: %.c
$(call mesa-cc-c,MESA)
+$(MESA_OBJ_DIR)/%.o: %.cpp
+ $(call mesa-cxx-c,MESA)
+
$(MESA_OBJ_DIR)/%.o: %.S
$(call mesa-cc-c,MESA)
$(ES1_OBJ_DIR)/%.o: %.c
$(call mesa-cc-c,ES1)
+$(ES1_OBJ_DIR)/%.o: %.cpp
+ $(call mesa-cxx-c,ES1)
+
$(ES1_OBJ_DIR)/%.o: %.S
$(call mesa-cc-c,ES1)
$(ES2_OBJ_DIR)/%.o: %.c
$(call mesa-cc-c,ES2)
+$(ES2_OBJ_DIR)/%.o: %.cpp
+ $(call mesa-cxx-c,ES2)
+
$(ES2_OBJ_DIR)/%.o: %.S
$(call mesa-cc-c,ES2)
# Default: build dependencies, then asm_subdirs, GLSL built-in lib,
# then convenience libs (.a) and finally the device drivers:
-default: $(DEPENDS) asm_subdirs glsl_builtin \
+default: $(DEPENDS) asm_subdirs \
$(MESA_LIBS) $(ES1_LIBS) $(ES2_LIBS) driver_subdirs
main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py
@@ -121,12 +139,6 @@ asm_subdirs:
######################################################################
-# GLSL built-in library
-glsl_builtin:
- (cd slang/library && $(MAKE)) || exit 1 ;
-
-
-######################################################################
# Dependency generation
depend: $(ALL_SOURCES)
@@ -241,7 +253,6 @@ clean: clean-es1 clean-es2
-rm -f depend depend.bak libmesa.a libmesagallium.a
-rm -f drivers/*/*.o
-rm -f *.pc
- -rm -f slang/library/*_gc.h
-@cd drivers/dri && $(MAKE) clean
-@cd drivers/x11 && $(MAKE) clean
-@cd drivers/osmesa && $(MAKE) clean
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index d31b957234b..28598f4a17c 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -10,6 +10,7 @@ if env['platform'] != 'winddk':
env.Append(CPPPATH = [
'#/src/mapi',
+ '#/src/glsl',
'#/src/mesa',
])
@@ -19,6 +20,7 @@ if env['platform'] != 'winddk':
'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers
'WIN32_THREADS', # use Win32 thread API
])
+ env.Prepend(CPPPATH = ['#src/talloc'])
#
# Source files
@@ -51,6 +53,7 @@ if env['platform'] != 'winddk':
'main/dlist.c',
'main/dlopen.c',
'main/drawpix.c',
+ 'main/drawtex.c',
'main/enable.c',
'main/enums.c',
'main/eval.c',
@@ -104,6 +107,7 @@ if env['platform'] != 'winddk':
'main/texgetimage.c',
'main/teximage.c',
'main/texobj.c',
+ 'main/texpal.c',
'main/texparam.c',
'main/texrender.c',
'main/texstate.c',
@@ -174,6 +178,7 @@ if env['platform'] != 'winddk':
'state_tracker/st_cb_condrender.c',
'state_tracker/st_cb_flush.c',
'state_tracker/st_cb_drawpixels.c',
+ 'state_tracker/st_cb_drawtex.c',
'state_tracker/st_cb_eglimage.c',
'state_tracker/st_cb_fbo.c',
'state_tracker/st_cb_feedback.c',
@@ -201,6 +206,7 @@ if env['platform'] != 'winddk':
program_sources = [
'program/arbprogparse.c',
'program/hash_table.c',
+ 'program/ir_to_mesa.cpp',
'program/lex.yy.c',
'program/nvfragparse.c',
'program/nvvertparse.c',
@@ -221,36 +227,13 @@ if env['platform'] != 'winddk':
'program/symbol_table.c',
]
- slang_sources = [
- 'slang/slang_builtin.c',
- 'slang/slang_codegen.c',
- 'slang/slang_compile.c',
- 'slang/slang_compile_function.c',
- 'slang/slang_compile_operation.c',
- 'slang/slang_compile_struct.c',
- 'slang/slang_compile_variable.c',
- 'slang/slang_emit.c',
- 'slang/slang_ir.c',
- 'slang/slang_label.c',
- 'slang/slang_link.c',
- 'slang/slang_log.c',
- 'slang/slang_mem.c',
- 'slang/slang_print.c',
- 'slang/slang_simplify.c',
- 'slang/slang_storage.c',
- 'slang/slang_typeinfo.c',
- 'slang/slang_vartable.c',
- 'slang/slang_utility.c',
- ]
-
mesa_sources = (
main_sources +
math_sources +
program_sources +
vbo_sources +
vf_sources +
- statetracker_sources +
- slang_sources
+ statetracker_sources
)
#
@@ -328,8 +311,6 @@ if env['platform'] != 'winddk':
# build dir) to the include path
env.Append(CPPPATH = [matypes[0].dir])
- SConscript('slang/library/SConscript')
-
#
# Libraries
#
diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template
index 8cb25439e48..a00018cafa7 100644
--- a/src/mesa/drivers/dri/Makefile.template
+++ b/src/mesa/drivers/dri/Makefile.template
@@ -17,6 +17,7 @@ COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \
INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES)
OBJECTS = $(C_SOURCES:.c=.o) \
+ $(CXX_SOURCES:.cpp=.o) \
$(ASM_SOURCES:.S=.o)
@@ -33,12 +34,16 @@ SHARED_INCLUDES = \
$(LIBDRM_CFLAGS)
CFLAGS += $(API_DEFINES)
+CXXFLAGS += $(API_DEFINES)
##### RULES #####
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
+.cpp.o:
+ $(CC) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@
+
.S.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
@@ -54,9 +59,9 @@ lib: symlinks subdirs depend
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(EXTRA_MODULES) Makefile \
$(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/src/mesa/drivers/dri/common/dri_test.o
- $(MKLIB) -o [email protected] -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ $(MKLIB) -o [email protected] -noprefix -linker '$(CXX)' -ldflags '$(LDFLAGS)' \
$(OBJECTS) $(MESA_MODULES) $(EXTRA_MODULES) $(DRI_LIB_DEPS)
- $(CC) $(CFLAGS) -o [email protected] $(TOP)/src/mesa/drivers/dri/common/dri_test.o [email protected] $(DRI_LIB_DEPS)
+ $(CXX) $(CFLAGS) -o [email protected] $(TOP)/src/mesa/drivers/dri/common/dri_test.o [email protected] $(DRI_LIB_DEPS)
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index dce84ef0deb..a581c6663f2 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -32,6 +32,7 @@
#include "drm_sarea.h"
#include "utils.h"
#include "xmlpool.h"
+#include "../glsl/glsl_parser_extras.h"
PUBLIC const char __dri2ConfigOptions[] =
DRI_CONF_BEGIN
@@ -707,6 +708,8 @@ static void driDestroyScreen(__DRIscreen *psp)
* stream open to the X-server anymore.
*/
+ _mesa_destroy_shader_compiler();
+
if (psp->DriverAPI.DestroyScreen)
(*psp->DriverAPI.DestroyScreen)(psp);
@@ -714,6 +717,9 @@ static void driDestroyScreen(__DRIscreen *psp)
(void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
(void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
(void)drmCloseOnce(psp->fd);
+ } else {
+ driDestroyOptionCache(&psp->optionCache);
+ driDestroyOptionInfo(&psp->optionInfo);
}
free(psp);
@@ -839,7 +845,6 @@ dri2CreateNewScreen(int scrn, int fd,
static const __DRIextension *emptyExtensionList[] = { NULL };
__DRIscreen *psp;
drmVersionPtr version;
- driOptionCache options;
if (driDriverAPI.InitScreen2 == NULL)
return NULL;
@@ -873,8 +878,10 @@ dri2CreateNewScreen(int scrn, int fd,
psp->DriverAPI = driDriverAPI;
- driParseOptionInfo(&options, __dri2ConfigOptions, __dri2NConfigOptions);
- driParseConfigFiles(&psp->optionCache, &options, psp->myNum, "dri2");
+ driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions,
+ __dri2NConfigOptions);
+ driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum,
+ "dri2");
return psp;
}
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index bc647ff8130..5096d22cad3 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -513,7 +513,11 @@ struct __DRIscreenRec {
*
* This pointer is never touched by the DRI layer.
*/
+#ifdef __cplusplus
+ void *priv;
+#else
void *private;
+#endif
/* Extensions provided by the loader. */
const __DRIgetDrawableInfoExtension *getDrawableInfo;
@@ -532,6 +536,7 @@ struct __DRIscreenRec {
/* The lock actually in use, old sarea or DRI2 */
drmLock *lock;
+ driOptionCache optionInfo;
driOptionCache optionCache;
unsigned int api_mask;
};
diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c
index d52ea9812f7..8ddce6d82a5 100644
--- a/src/mesa/drivers/dri/i915/i830_context.c
+++ b/src/mesa/drivers/dri/i915/i830_context.c
@@ -27,7 +27,6 @@
#include "i830_context.h"
#include "main/imports.h"
-#include "texmem.h"
#include "tnl/tnl.h"
#include "tnl/t_vertex.h"
#include "tnl/t_context.h"
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index b3fe1c05d66..d8715cf026d 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -174,6 +174,8 @@ i915CreateContext(int api,
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+ ctx->Shader.EmitNoIfs = GL_TRUE;
+
ctx->Const.MaxDrawBuffers = 1;
_tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12,
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index f1505dc5e73..4a2e6209d07 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -143,6 +143,20 @@ src_vector(struct i915_fragment_program *p,
}
break;
+ case PROGRAM_OUTPUT:
+ switch (source->Index) {
+ case FRAG_RESULT_COLOR:
+ src = UREG(REG_TYPE_OC, 0);
+ break;
+ case FRAG_RESULT_DEPTH:
+ src = UREG(REG_TYPE_OD, 0);
+ break;
+ default:
+ i915_program_error(p, "Bad source->Index: %d", source->Index);
+ return 0;
+ }
+ break;
+
/* Various paramters and env values. All emitted to
* hardware as program constants.
*/
@@ -472,6 +486,18 @@ upload_program(struct i915_fragment_program *p)
swizzle(tmp, X, X, X, X));
break;
+ case OPCODE_DP2:
+ src0 = src_vector(p, &inst->SrcReg[0], program);
+ src1 = src_vector(p, &inst->SrcReg[1], program);
+ i915_emit_arith(p,
+ A0_DP3,
+ get_result_vector(p, inst),
+ get_result_flags(inst), 0,
+ swizzle(src0, X, Y, ZERO, ZERO),
+ swizzle(src1, X, Y, ZERO, ZERO),
+ 0);
+ break;
+
case OPCODE_DP3:
EMIT_2ARG_ARITH(A0_DP3);
break;
@@ -957,6 +983,41 @@ upload_program(struct i915_fragment_program *p)
0);
break;
+ case OPCODE_SSG:
+ dst = get_result_vector(p, inst);
+ flags = get_result_flags(inst);
+ src0 = src_vector(p, &inst->SrcReg[0], program);
+ tmp = i915_get_utemp(p);
+
+ /* tmp = (src < 0.0) */
+ i915_emit_arith(p,
+ A0_SLT,
+ tmp,
+ flags, 0,
+ src0,
+ swizzle(src0, ZERO, ZERO, ZERO, ZERO),
+ 0);
+
+ /* dst = (0.0 < src) */
+ i915_emit_arith(p,
+ A0_SLT,
+ dst,
+ flags, 0,
+ swizzle(src0, ZERO, ZERO, ZERO, ZERO),
+ src0,
+ 0);
+
+ /* dst = (src > 0.0) - (src < 0.0) */
+ i915_emit_arith(p,
+ A0_ADD,
+ dst,
+ flags, 0,
+ dst,
+ negate(tmp, 1, 1, 1, 1),
+ 0);
+
+ break;
+
case OPCODE_SUB:
src0 = src_vector(p, &inst->SrcReg[0], program);
src1 = src_vector(p, &inst->SrcReg[1], program);
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index e381a5c714b..bea48e13138 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -104,6 +104,11 @@ C_SOURCES = \
$(COMMON_SOURCES) \
$(DRIVER_SOURCES)
+CXX_SOURCES = \
+ brw_fs.cpp \
+ brw_fs_channel_expressions.cpp \
+ brw_fs_vector_splitting.cpp
+
ASM_SOURCES =
DRIVER_DEFINES = -I../intel
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 6d064b822e5..d2b20165f9d 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -144,7 +144,8 @@ GLboolean brwCreateContext( int api,
brw->CMD_VF_STATISTICS = CMD_VF_STATISTICS_GM45;
brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45;
brw->has_surface_tile_offset = GL_TRUE;
- brw->has_compr4 = GL_TRUE;
+ if (intel->gen < 6)
+ brw->has_compr4 = GL_TRUE;
brw->has_aa_line_parameters = GL_TRUE;
brw->has_pln = GL_TRUE;
} else {
@@ -153,7 +154,11 @@ GLboolean brwCreateContext( int api,
}
/* WM maximum threads is number of EUs times number of threads per EU. */
- if (intel->gen == 5) {
+ if (intel->gen >= 6) {
+ brw->urb.size = 1024;
+ brw->vs_max_threads = 60;
+ brw->wm_max_threads = 80;
+ } else if (intel->gen == 5) {
brw->urb.size = 1024;
brw->vs_max_threads = 72;
brw->wm_max_threads = 12 * 6;
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index cc4e6638e8b..703a7de78d1 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -179,6 +179,16 @@ struct brw_fragment_program {
GLbitfield tex_units_used;
};
+struct brw_shader {
+ struct gl_shader base;
+
+ /** Shader IR transformed for native compile, at link time. */
+ struct exec_list *ir;
+};
+
+struct brw_shader_program {
+ struct gl_shader_program base;
+};
/* Data about a particular attempt to compile a program. Note that
* there can be many of these, each in a different GL state
@@ -654,7 +664,13 @@ struct brw_context
drm_intel_bo *prog_bo;
drm_intel_bo *state_bo;
- drm_intel_bo *const_bo;
+ drm_intel_bo *const_bo; /* pull constant buffer. */
+ /**
+ * This is the push constant BO on gen6.
+ *
+ * Pre-gen6, push constants live in the CURBE.
+ */
+ drm_intel_bo *push_const_bo;
} wm;
@@ -686,7 +702,13 @@ struct brw_context
#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a)
-
+struct brw_instruction_info {
+ char *name;
+ int nsrc;
+ int ndst;
+ GLboolean is_arith;
+};
+extern const struct brw_instruction_info brw_opcodes[128];
/*======================================================================
* brw_vtbl.c
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index f7a68cead7c..6b8e9e05d08 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -686,6 +686,9 @@
#define BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_GEN5 1
#define BRW_SAMPLER_MESSAGE_SAMPLE_LOD_GEN5 2
#define BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_GEN5 3
+#define BRW_SAMPLER_MESSAGE_SAMPLE_DERIVS_GEN5 4
+#define BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE_GEN5 5
+#define BRW_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE_GEN5 6
/* for GEN5 only */
#define BRW_SAMPLER_SIMD_MODE_SIMD4X2 0
diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c
index d2307145361..f74a236834b 100644
--- a/src/mesa/drivers/dri/i965/brw_disasm.c
+++ b/src/mesa/drivers/dri/i965/brw_disasm.c
@@ -159,6 +159,11 @@ char *saturate[2] = {
[1] = ".sat"
};
+char *accwr[2] = {
+ [0] = "",
+ [1] = "AccWrEnable"
+};
+
char *exec_size[8] = {
[0] = "1",
[1] = "2",
@@ -206,6 +211,7 @@ char *compr_ctrl[4] = {
[0] = "",
[1] = "sechalf",
[2] = "compr",
+ [3] = "compr4",
};
char *dep_ctrl[4] = {
@@ -235,6 +241,16 @@ char *reg_encoding[8] = {
[7] = "F"
};
+int reg_type_size[8] = {
+ [0] = 4,
+ [1] = 4,
+ [2] = 2,
+ [3] = 2,
+ [4] = 1,
+ [5] = 1,
+ [7] = 4
+};
+
char *imm_encoding[8] = {
[0] = "UD",
[1] = "D",
@@ -423,6 +439,11 @@ static int print_opcode (FILE *file, int id)
static int reg (FILE *file, GLuint _reg_file, GLuint _reg_nr)
{
int err = 0;
+
+ /* Clear the Compr4 instruction compression bit. */
+ if (_reg_file == BRW_MESSAGE_REGISTER_FILE)
+ _reg_nr &= ~(1 << 7);
+
if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
switch (_reg_nr & 0xf0) {
case BRW_ARF_NULL:
@@ -476,7 +497,8 @@ static int dest (FILE *file, struct brw_instruction *inst)
if (err == -1)
return 0;
if (inst->bits1.da1.dest_subreg_nr)
- format (file, ".%d", inst->bits1.da1.dest_subreg_nr);
+ format (file, ".%d", inst->bits1.da1.dest_subreg_nr /
+ reg_type_size[inst->bits1.da1.dest_reg_type]);
format (file, "<%d>", inst->bits1.da1.dest_horiz_stride);
err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da1.dest_reg_type, NULL);
}
@@ -484,7 +506,8 @@ static int dest (FILE *file, struct brw_instruction *inst)
{
string (file, "g[a0");
if (inst->bits1.ia1.dest_subreg_nr)
- format (file, ".%d", inst->bits1.ia1.dest_subreg_nr);
+ format (file, ".%d", inst->bits1.ia1.dest_subreg_nr /
+ reg_type_size[inst->bits1.ia1.dest_reg_type]);
if (inst->bits1.ia1.dest_indirect_offset)
format (file, " %d", inst->bits1.ia1.dest_indirect_offset);
string (file, "]");
@@ -500,7 +523,8 @@ static int dest (FILE *file, struct brw_instruction *inst)
if (err == -1)
return 0;
if (inst->bits1.da16.dest_subreg_nr)
- format (file, ".%d", inst->bits1.da16.dest_subreg_nr);
+ format (file, ".%d", inst->bits1.da16.dest_subreg_nr /
+ reg_type_size[inst->bits1.da16.dest_reg_type]);
string (file, "<1>");
err |= control (file, "writemask", writemask, inst->bits1.da16.dest_writemask, NULL);
err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da16.dest_reg_type, NULL);
@@ -541,7 +565,7 @@ static int src_da1 (FILE *file, GLuint type, GLuint _reg_file,
if (err == -1)
return 0;
if (sub_reg_num)
- format (file, ".%d", sub_reg_num);
+ format (file, ".%d", sub_reg_num / reg_type_size[type]); /* use formal style like spec */
src_align1_region (file, _vert_stride, _width, _horiz_stride);
err |= control (file, "src reg encoding", reg_encoding, type, NULL);
return err;
@@ -595,11 +619,12 @@ static int src_da16 (FILE *file,
if (err == -1)
return 0;
if (_subreg_nr)
- format (file, ".%d", _subreg_nr);
+ /* bit4 for subreg number byte addressing. Make this same meaning as
+ in da1 case, so output looks consistent. */
+ format (file, ".%d", 16 / reg_type_size[_reg_type]);
string (file, "<");
err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
string (file, ",4,1>");
- err |= control (file, "src da16 reg type", reg_encoding, _reg_type, NULL);
/*
* Three kinds of swizzle display:
* identity - nothing printed
@@ -863,12 +888,25 @@ int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
inst->bits3.math.precision, &space);
break;
case BRW_MESSAGE_TARGET_SAMPLER:
- format (file, " (%d, %d, ",
- inst->bits3.sampler.binding_table_index,
- inst->bits3.sampler.sampler);
- err |= control (file, "sampler target format", sampler_target_format,
- inst->bits3.sampler.return_format, NULL);
- string (file, ")");
+ if (gen >= 5) {
+ format (file, " (%d, %d, %d, %d)",
+ inst->bits3.sampler_gen5.binding_table_index,
+ inst->bits3.sampler_gen5.sampler,
+ inst->bits3.sampler_gen5.msg_type,
+ inst->bits3.sampler_gen5.simd_mode);
+ } else if (0 /* FINISHME: is_g4x */) {
+ format (file, " (%d, %d)",
+ inst->bits3.sampler_g4x.binding_table_index,
+ inst->bits3.sampler_g4x.sampler);
+ } else {
+ format (file, " (%d, %d, ",
+ inst->bits3.sampler.binding_table_index,
+ inst->bits3.sampler.sampler);
+ err |= control (file, "sampler target format",
+ sampler_target_format,
+ inst->bits3.sampler.return_format, NULL);
+ string (file, ")");
+ }
break;
case BRW_MESSAGE_TARGET_DATAPORT_READ:
if (gen >= 6) {
@@ -929,6 +967,11 @@ int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
inst->bits3.urb.used, &space);
err |= control (file, "urb complete", urb_complete,
inst->bits3.urb.complete, &space);
+ if (gen >= 5) {
+ format (file, " mlen %d, rlen %d\n",
+ inst->bits3.urb_gen5.msg_length,
+ inst->bits3.urb_gen5.response_length);
+ }
break;
case BRW_MESSAGE_TARGET_THREAD_SPAWNER:
break;
@@ -957,8 +1000,19 @@ int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
err |= control(file, "access mode", access_mode, inst->header.access_mode, &space);
err |= control (file, "mask control", mask_ctrl, inst->header.mask_control, &space);
err |= control (file, "dependency control", dep_ctrl, inst->header.dependency_control, &space);
- err |= control (file, "compression control", compr_ctrl, inst->header.compression_control, &space);
+
+ if (inst->header.compression_control == BRW_COMPRESSION_COMPRESSED &&
+ opcode[inst->header.opcode].ndst > 0 &&
+ inst->bits1.da1.dest_reg_file == BRW_MESSAGE_REGISTER_FILE &&
+ inst->bits1.da1.dest_reg_nr & (1 << 7)) {
+ format (file, " compr4");
+ } else {
+ err |= control (file, "compression control", compr_ctrl,
+ inst->header.compression_control, &space);
+ }
err |= control (file, "thread control", thread_ctrl, inst->header.thread_control, &space);
+ if (gen >= 6)
+ err |= control (file, "acc write control", accwr, inst->header.acc_wr_control, &space);
if (inst->header.opcode == BRW_OPCODE_SEND)
err |= control (file, "end of thread", end_of_thread,
inst->bits3.generic.end_of_thread, &space);
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index f07aab86e90..249e874ab1a 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -476,7 +476,7 @@ static void brw_emit_vertices(struct brw_context *brw)
if (brw->vb.nr_enabled == 0) {
BEGIN_BATCH(3);
OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
- if (IS_GEN6(intel->intelScreen->deviceID)) {
+ if (intel->gen >= 6) {
OUT_BATCH((0 << GEN6_VE0_INDEX_SHIFT) |
GEN6_VE0_VALID |
(BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
@@ -553,7 +553,7 @@ static void brw_emit_vertices(struct brw_context *brw)
break;
}
- if (IS_GEN6(intel->intelScreen->deviceID)) {
+ if (intel->gen >= 6) {
OUT_BATCH((i << GEN6_VE0_INDEX_SHIFT) |
GEN6_VE0_VALID |
(format << BRW_VE0_FORMAT_SHIFT) |
diff --git a/src/mesa/drivers/dri/i965/brw_eu.c b/src/mesa/drivers/dri/i965/brw_eu.c
index 4e7c1226ad4..2ff39e8e64a 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.c
+++ b/src/mesa/drivers/dri/i965/brw_eu.c
@@ -85,6 +85,12 @@ void brw_set_saturate( struct brw_compile *p, GLuint value )
p->current->header.saturate = value;
}
+void brw_set_acc_write_control(struct brw_compile *p, GLuint value)
+{
+ if (p->brw->intel.gen >= 6)
+ p->current->header.acc_wr_control = value;
+}
+
void brw_push_insn_state( struct brw_compile *p )
{
assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index ffdddd0a388..c63db164609 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -633,6 +633,8 @@ static INLINE struct brw_reg brw_swizzle( struct brw_reg reg,
GLuint z,
GLuint w)
{
+ assert(reg.file != BRW_IMMEDIATE_VALUE);
+
reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x),
BRW_GET_SWZ(reg.dw1.bits.swizzle, y),
BRW_GET_SWZ(reg.dw1.bits.swizzle, z),
@@ -650,6 +652,7 @@ static INLINE struct brw_reg brw_swizzle1( struct brw_reg reg,
static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
GLuint mask )
{
+ assert(reg.file != BRW_IMMEDIATE_VALUE);
reg.dw1.bits.writemask &= mask;
return reg;
}
@@ -657,6 +660,7 @@ static INLINE struct brw_reg brw_writemask( struct brw_reg reg,
static INLINE struct brw_reg brw_set_writemask( struct brw_reg reg,
GLuint mask )
{
+ assert(reg.file != BRW_IMMEDIATE_VALUE);
reg.dw1.bits.writemask = mask;
return reg;
}
@@ -766,6 +770,7 @@ void brw_set_compression_control( struct brw_compile *p, GLboolean control );
void brw_set_predicate_control_flag_value( struct brw_compile *p, GLuint value );
void brw_set_predicate_control( struct brw_compile *p, GLuint pc );
void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional );
+void brw_set_acc_write_control(struct brw_compile *p, GLuint value);
void brw_init_compile( struct brw_context *, struct brw_compile *p );
const GLuint *brw_get_program( struct brw_compile *p, GLuint *sz );
@@ -840,6 +845,7 @@ void brw_ff_sync(struct brw_compile *p,
GLboolean eot);
void brw_fb_WRITE(struct brw_compile *p,
+ int dispatch_width,
struct brw_reg dest,
GLuint msg_reg_nr,
struct brw_reg src0,
@@ -925,8 +931,8 @@ struct brw_instruction *brw_DO(struct brw_compile *p,
struct brw_instruction *brw_WHILE(struct brw_compile *p,
struct brw_instruction *patch_insn);
-struct brw_instruction *brw_BREAK(struct brw_compile *p);
-struct brw_instruction *brw_CONT(struct brw_compile *p);
+struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count);
+struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count);
/* Forward jumps:
*/
void brw_land_fwd_jump(struct brw_compile *p,
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 0d5d17f501d..0906150613b 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -75,6 +75,8 @@ static void brw_set_dest( struct brw_instruction *insn,
else {
insn->bits1.da16.dest_subreg_nr = dest.subnr / 16;
insn->bits1.da16.dest_writemask = dest.dw1.bits.writemask;
+ /* even ignored in da16, still need to set as '01' */
+ insn->bits1.da16.dest_horiz_stride = 1;
}
}
else {
@@ -90,6 +92,8 @@ static void brw_set_dest( struct brw_instruction *insn,
}
else {
insn->bits1.ia16.dest_indirect_offset = dest.dw1.bits.indirect_offset;
+ /* even ignored in da16, still need to set as '01' */
+ insn->bits1.ia16.dest_horiz_stride = 1;
}
}
@@ -368,9 +372,23 @@ static void brw_set_dp_write_message( struct brw_context *brw,
GLuint send_commit_msg)
{
struct intel_context *intel = &brw->intel;
- brw_set_src1(insn, brw_imm_d(0));
+ brw_set_src1(insn, brw_imm_ud(0));
- if (intel->gen == 5) {
+ if (intel->gen >= 6) {
+ insn->bits3.dp_render_cache.binding_table_index = binding_table_index;
+ insn->bits3.dp_render_cache.msg_control = msg_control;
+ insn->bits3.dp_render_cache.pixel_scoreboard_clear = pixel_scoreboard_clear;
+ insn->bits3.dp_render_cache.msg_type = msg_type;
+ insn->bits3.dp_render_cache.send_commit_msg = send_commit_msg;
+ insn->bits3.dp_render_cache.header_present = 0; /* XXX */
+ insn->bits3.dp_render_cache.response_length = response_length;
+ insn->bits3.dp_render_cache.msg_length = msg_length;
+ insn->bits3.dp_render_cache.end_of_thread = end_of_thread;
+ insn->header.destreg__conditionalmod = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
+ /* XXX really need below? */
+ insn->bits2.send_gen5.sfid = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
+ insn->bits2.send_gen5.end_of_thread = end_of_thread;
+ } else if (intel->gen == 5) {
insn->bits3.dp_write_gen5.binding_table_index = binding_table_index;
insn->bits3.dp_write_gen5.msg_control = msg_control;
insn->bits3.dp_write_gen5.pixel_scoreboard_clear = pixel_scoreboard_clear;
@@ -759,7 +777,7 @@ void brw_ENDIF(struct brw_compile *p,
}
}
-struct brw_instruction *brw_BREAK(struct brw_compile *p)
+struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count)
{
struct brw_instruction *insn;
insn = next_insn(p, BRW_OPCODE_BREAK);
@@ -770,10 +788,11 @@ struct brw_instruction *brw_BREAK(struct brw_compile *p)
insn->header.execution_size = BRW_EXECUTE_8;
/* insn->header.mask_control = BRW_MASK_DISABLE; */
insn->bits3.if_else.pad0 = 0;
+ insn->bits3.if_else.pop_count = pop_count;
return insn;
}
-struct brw_instruction *brw_CONT(struct brw_compile *p)
+struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count)
{
struct brw_instruction *insn;
insn = next_insn(p, BRW_OPCODE_CONTINUE);
@@ -784,6 +803,7 @@ struct brw_instruction *brw_CONT(struct brw_compile *p)
insn->header.execution_size = BRW_EXECUTE_8;
/* insn->header.mask_control = BRW_MASK_DISABLE; */
insn->bits3.if_else.pad0 = 0;
+ insn->bits3.if_else.pop_count = pop_count;
return insn;
}
@@ -1332,6 +1352,7 @@ void brw_dp_READ_4_vs_relative(struct brw_compile *p,
void brw_fb_WRITE(struct brw_compile *p,
+ int dispatch_width,
struct brw_reg dest,
GLuint msg_reg_nr,
struct brw_reg src0,
@@ -1340,22 +1361,40 @@ void brw_fb_WRITE(struct brw_compile *p,
GLuint response_length,
GLboolean eot)
{
- struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
-
+ struct intel_context *intel = &p->brw->intel;
+ struct brw_instruction *insn;
+ GLuint msg_control, msg_type;
+
+ insn = next_insn(p, BRW_OPCODE_SEND);
insn->header.predicate_control = 0; /* XXX */
- insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditionalmod = msg_reg_nr;
-
+ insn->header.compression_control = BRW_COMPRESSION_NONE;
+
+ if (intel->gen >= 6) {
+ /* headerless version, just submit color payload */
+ src0 = brw_message_reg(msg_reg_nr);
+
+ msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE_GEN6;
+ } else {
+ insn->header.destreg__conditionalmod = msg_reg_nr;
+
+ msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE;
+ }
+
+ if (dispatch_width == 16)
+ msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE;
+ else
+ msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01;
+
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
brw_set_dp_write_message(p->brw,
insn,
binding_table_index,
- BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE, /* msg_control */
- BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */
+ msg_control,
+ msg_type,
msg_length,
1, /* pixel scoreboard */
- response_length,
+ response_length,
eot,
0 /* send_commit_msg */);
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
new file mode 100644
index 00000000000..34c5d5262fb
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -0,0 +1,1924 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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:
+ * Eric Anholt <[email protected]>
+ *
+ */
+
+extern "C" {
+
+#include <sys/types.h>
+
+#include "main/macros.h"
+#include "main/shaderobj.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_optimize.h"
+#include "program/hash_table.h"
+#include "brw_context.h"
+#include "brw_eu.h"
+#include "brw_wm.h"
+#include "talloc.h"
+}
+#include "../glsl/glsl_types.h"
+#include "../glsl/ir_optimization.h"
+#include "../glsl/ir_print_visitor.h"
+
+enum register_file {
+ ARF = BRW_ARCHITECTURE_REGISTER_FILE,
+ GRF = BRW_GENERAL_REGISTER_FILE,
+ MRF = BRW_MESSAGE_REGISTER_FILE,
+ IMM = BRW_IMMEDIATE_VALUE,
+ FIXED_HW_REG, /* a struct brw_reg */
+ UNIFORM, /* prog_data->params[hw_reg] */
+ BAD_FILE
+};
+
+enum fs_opcodes {
+ FS_OPCODE_FB_WRITE = 256,
+ FS_OPCODE_RCP,
+ FS_OPCODE_RSQ,
+ FS_OPCODE_SQRT,
+ FS_OPCODE_EXP2,
+ FS_OPCODE_LOG2,
+ FS_OPCODE_POW,
+ FS_OPCODE_SIN,
+ FS_OPCODE_COS,
+ FS_OPCODE_DDX,
+ FS_OPCODE_DDY,
+ FS_OPCODE_LINTERP,
+ FS_OPCODE_TEX,
+ FS_OPCODE_TXB,
+ FS_OPCODE_TXL,
+ FS_OPCODE_DISCARD,
+};
+
+static int using_new_fs = -1;
+
+struct gl_shader *
+brw_new_shader(GLcontext *ctx, GLuint name, GLuint type)
+{
+ struct brw_shader *shader;
+
+ shader = talloc_zero(NULL, struct brw_shader);
+ if (shader) {
+ shader->base.Type = type;
+ shader->base.Name = name;
+ _mesa_init_shader(ctx, &shader->base);
+ }
+
+ return &shader->base;
+}
+
+struct gl_shader_program *
+brw_new_shader_program(GLcontext *ctx, GLuint name)
+{
+ struct brw_shader_program *prog;
+ prog = talloc_zero(NULL, struct brw_shader_program);
+ if (prog) {
+ prog->base.Name = name;
+ _mesa_init_shader_program(ctx, &prog->base);
+ }
+ return &prog->base;
+}
+
+GLboolean
+brw_compile_shader(GLcontext *ctx, struct gl_shader *shader)
+{
+ if (!_mesa_ir_compile_shader(ctx, shader))
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+GLboolean
+brw_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
+{
+ if (using_new_fs == -1)
+ using_new_fs = getenv("INTEL_NEW_FS") != NULL;
+
+ for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
+ struct brw_shader *shader = (struct brw_shader *)prog->_LinkedShaders[i];
+
+ if (using_new_fs && shader->base.Type == GL_FRAGMENT_SHADER) {
+ void *mem_ctx = talloc_new(NULL);
+ bool progress;
+
+ if (shader->ir)
+ talloc_free(shader->ir);
+ shader->ir = new(shader) exec_list;
+ clone_ir_list(mem_ctx, shader->ir, shader->base.ir);
+
+ do_mat_op_to_vec(shader->ir);
+ do_mod_to_fract(shader->ir);
+ do_div_to_mul_rcp(shader->ir);
+ do_sub_to_add_neg(shader->ir);
+ do_explog_to_explog2(shader->ir);
+
+ brw_do_channel_expressions(shader->ir);
+ brw_do_vector_splitting(shader->ir);
+
+ do {
+ progress = false;
+
+ progress = do_common_optimization(shader->ir, true) || progress;
+ } while (progress);
+
+ validate_ir_tree(shader->ir);
+
+ reparent_ir(shader->ir, shader->ir);
+ talloc_free(mem_ctx);
+ }
+ }
+
+ if (!_mesa_ir_link_shader(ctx, prog))
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+static int
+type_size(const struct glsl_type *type)
+{
+ unsigned int size, i;
+
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ return type->components();
+ case GLSL_TYPE_ARRAY:
+ /* FINISHME: uniform/varying arrays. */
+ return type_size(type->fields.array) * type->length;
+ case GLSL_TYPE_STRUCT:
+ size = 0;
+ for (i = 0; i < type->length; i++) {
+ size += type_size(type->fields.structure[i].type);
+ }
+ return size;
+ case GLSL_TYPE_SAMPLER:
+ /* Samplers take up no register space, since they're baked in at
+ * link time.
+ */
+ return 0;
+ default:
+ assert(!"not reached");
+ return 0;
+ }
+}
+
+class fs_reg {
+public:
+ /* Callers of this talloc-based new need not call delete. It's
+ * easier to just talloc_free 'ctx' (or any of its ancestors). */
+ static void* operator new(size_t size, void *ctx)
+ {
+ void *node;
+
+ node = talloc_size(ctx, size);
+ assert(node != NULL);
+
+ return node;
+ }
+
+ /** Generic unset register constructor. */
+ fs_reg()
+ {
+ this->file = BAD_FILE;
+ this->reg = 0;
+ this->reg_offset = 0;
+ this->hw_reg = -1;
+ this->negate = 0;
+ this->abs = 0;
+ }
+
+ /** Immediate value constructor. */
+ fs_reg(float f)
+ {
+ this->file = IMM;
+ this->reg = 0;
+ this->hw_reg = 0;
+ this->type = BRW_REGISTER_TYPE_F;
+ this->imm.f = f;
+ this->negate = 0;
+ this->abs = 0;
+ }
+
+ /** Immediate value constructor. */
+ fs_reg(int32_t i)
+ {
+ this->file = IMM;
+ this->reg = 0;
+ this->hw_reg = 0;
+ this->type = BRW_REGISTER_TYPE_D;
+ this->imm.i = i;
+ this->negate = 0;
+ this->abs = 0;
+ }
+
+ /** Immediate value constructor. */
+ fs_reg(uint32_t u)
+ {
+ this->file = IMM;
+ this->reg = 0;
+ this->hw_reg = 0;
+ this->type = BRW_REGISTER_TYPE_UD;
+ this->imm.u = u;
+ this->negate = 0;
+ this->abs = 0;
+ }
+
+ /** Fixed brw_reg Immediate value constructor. */
+ fs_reg(struct brw_reg fixed_hw_reg)
+ {
+ this->file = FIXED_HW_REG;
+ this->fixed_hw_reg = fixed_hw_reg;
+ this->reg = 0;
+ this->hw_reg = 0;
+ this->type = fixed_hw_reg.type;
+ this->negate = 0;
+ this->abs = 0;
+ }
+
+ fs_reg(enum register_file file, int hw_reg);
+ fs_reg(class fs_visitor *v, const struct glsl_type *type);
+
+ /** Register file: ARF, GRF, MRF, IMM. */
+ enum register_file file;
+ /** Abstract register number. 0 = fixed hw reg */
+ int reg;
+ /** Offset within the abstract register. */
+ int reg_offset;
+ /** HW register number. Generally unset until register allocation. */
+ int hw_reg;
+ /** Register type. BRW_REGISTER_TYPE_* */
+ int type;
+ bool negate;
+ bool abs;
+ struct brw_reg fixed_hw_reg;
+
+ /** Value for file == BRW_IMMMEDIATE_FILE */
+ union {
+ int32_t i;
+ uint32_t u;
+ float f;
+ } imm;
+};
+
+static const fs_reg reg_undef;
+static const fs_reg reg_null(ARF, BRW_ARF_NULL);
+
+class fs_inst : public exec_node {
+public:
+ /* Callers of this talloc-based new need not call delete. It's
+ * easier to just talloc_free 'ctx' (or any of its ancestors). */
+ static void* operator new(size_t size, void *ctx)
+ {
+ void *node;
+
+ node = talloc_zero_size(ctx, size);
+ assert(node != NULL);
+
+ return node;
+ }
+
+ void init()
+ {
+ this->opcode = BRW_OPCODE_NOP;
+ this->saturate = false;
+ this->conditional_mod = BRW_CONDITIONAL_NONE;
+ this->predicated = false;
+ this->sampler = 0;
+ this->shadow_compare = false;
+ }
+
+ fs_inst()
+ {
+ init();
+ }
+
+ fs_inst(int opcode)
+ {
+ init();
+ this->opcode = opcode;
+ }
+
+ fs_inst(int opcode, fs_reg dst, fs_reg src0)
+ {
+ init();
+ this->opcode = opcode;
+ this->dst = dst;
+ this->src[0] = src0;
+ }
+
+ fs_inst(int opcode, fs_reg dst, fs_reg src0, fs_reg src1)
+ {
+ init();
+ this->opcode = opcode;
+ this->dst = dst;
+ this->src[0] = src0;
+ this->src[1] = src1;
+ }
+
+ fs_inst(int opcode, fs_reg dst, fs_reg src0, fs_reg src1, fs_reg src2)
+ {
+ init();
+ this->opcode = opcode;
+ this->dst = dst;
+ this->src[0] = src0;
+ this->src[1] = src1;
+ this->src[2] = src2;
+ }
+
+ int opcode; /* BRW_OPCODE_* or FS_OPCODE_* */
+ fs_reg dst;
+ fs_reg src[3];
+ bool saturate;
+ bool predicated;
+ int conditional_mod; /**< BRW_CONDITIONAL_* */
+
+ int mlen; /** SEND message length */
+ int sampler;
+ bool shadow_compare;
+
+ /** @{
+ * Annotation for the generated IR. One of the two can be set.
+ */
+ ir_instruction *ir;
+ const char *annotation;
+ /** @} */
+};
+
+class fs_visitor : public ir_visitor
+{
+public:
+
+ fs_visitor(struct brw_wm_compile *c, struct brw_shader *shader)
+ {
+ this->c = c;
+ this->p = &c->func;
+ this->brw = p->brw;
+ this->intel = &brw->intel;
+ this->ctx = &intel->ctx;
+ this->mem_ctx = talloc_new(NULL);
+ this->shader = shader;
+ this->fail = false;
+ this->next_abstract_grf = 1;
+ this->variable_ht = hash_table_ctor(0,
+ hash_table_pointer_hash,
+ hash_table_pointer_compare);
+
+ this->frag_color = NULL;
+ this->frag_data = NULL;
+ this->frag_depth = NULL;
+ this->first_non_payload_grf = 0;
+
+ this->current_annotation = NULL;
+ this->annotation_string = NULL;
+ this->annotation_ir = NULL;
+ }
+ ~fs_visitor()
+ {
+ talloc_free(this->mem_ctx);
+ hash_table_dtor(this->variable_ht);
+ }
+
+ fs_reg *variable_storage(ir_variable *var);
+
+ void visit(ir_variable *ir);
+ void visit(ir_assignment *ir);
+ void visit(ir_dereference_variable *ir);
+ void visit(ir_dereference_record *ir);
+ void visit(ir_dereference_array *ir);
+ void visit(ir_expression *ir);
+ void visit(ir_texture *ir);
+ void visit(ir_if *ir);
+ void visit(ir_constant *ir);
+ void visit(ir_swizzle *ir);
+ void visit(ir_return *ir);
+ void visit(ir_loop *ir);
+ void visit(ir_loop_jump *ir);
+ void visit(ir_discard *ir);
+ void visit(ir_call *ir);
+ void visit(ir_function *ir);
+ void visit(ir_function_signature *ir);
+
+ fs_inst *emit(fs_inst inst);
+ void assign_curb_setup();
+ void assign_urb_setup();
+ void assign_regs();
+ void generate_code();
+ void generate_fb_write(fs_inst *inst);
+ void generate_linterp(fs_inst *inst, struct brw_reg dst,
+ struct brw_reg *src);
+ void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src);
+ void generate_math(fs_inst *inst, struct brw_reg dst, struct brw_reg *src);
+ void generate_discard(fs_inst *inst);
+
+ void emit_dummy_fs();
+ void emit_interpolation();
+ void emit_pinterp(int location);
+ void emit_fb_writes();
+
+ struct brw_reg interp_reg(int location, int channel);
+
+ struct brw_context *brw;
+ struct intel_context *intel;
+ GLcontext *ctx;
+ struct brw_wm_compile *c;
+ struct brw_compile *p;
+ struct brw_shader *shader;
+ void *mem_ctx;
+ exec_list instructions;
+ int next_abstract_grf;
+ struct hash_table *variable_ht;
+ ir_variable *frag_color, *frag_data, *frag_depth;
+ int first_non_payload_grf;
+
+ /** @{ debug annotation info */
+ const char *current_annotation;
+ ir_instruction *base_ir;
+ const char **annotation_string;
+ ir_instruction **annotation_ir;
+ /** @} */
+
+ bool fail;
+
+ /* Result of last visit() method. */
+ fs_reg result;
+
+ fs_reg pixel_x;
+ fs_reg pixel_y;
+ fs_reg pixel_w;
+ fs_reg delta_x;
+ fs_reg delta_y;
+ fs_reg interp_attrs[64];
+
+ int grf_used;
+
+};
+
+/** Fixed HW reg constructor. */
+fs_reg::fs_reg(enum register_file file, int hw_reg)
+{
+ this->file = file;
+ this->reg = 0;
+ this->reg_offset = 0;
+ this->hw_reg = hw_reg;
+ this->type = BRW_REGISTER_TYPE_F;
+ this->negate = 0;
+ this->abs = 0;
+}
+
+/** Automatic reg constructor. */
+fs_reg::fs_reg(class fs_visitor *v, const struct glsl_type *type)
+{
+ this->file = GRF;
+ this->reg = v->next_abstract_grf;
+ this->reg_offset = 0;
+ v->next_abstract_grf += type_size(type);
+ this->hw_reg = -1;
+ this->negate = 0;
+ this->abs = 0;
+
+ switch (type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ this->type = BRW_REGISTER_TYPE_F;
+ break;
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_BOOL:
+ this->type = BRW_REGISTER_TYPE_D;
+ break;
+ case GLSL_TYPE_UINT:
+ this->type = BRW_REGISTER_TYPE_UD;
+ break;
+ default:
+ assert(!"not reached");
+ this->type = BRW_REGISTER_TYPE_F;
+ break;
+ }
+}
+
+fs_reg *
+fs_visitor::variable_storage(ir_variable *var)
+{
+ return (fs_reg *)hash_table_find(this->variable_ht, var);
+}
+
+void
+fs_visitor::visit(ir_variable *ir)
+{
+ fs_reg *reg = NULL;
+
+ if (strcmp(ir->name, "gl_FragColor") == 0) {
+ this->frag_color = ir;
+ } else if (strcmp(ir->name, "gl_FragData") == 0) {
+ this->frag_data = ir;
+ } else if (strcmp(ir->name, "gl_FragDepth") == 0) {
+ this->frag_depth = ir;
+ assert(!"FINISHME: this hangs currently.");
+ }
+
+ if (ir->mode == ir_var_in) {
+ reg = &this->interp_attrs[ir->location];
+ }
+
+ if (ir->mode == ir_var_uniform) {
+ const float *vec_values;
+ int param_index = c->prog_data.nr_params;
+
+ /* FINISHME: This is wildly incomplete. */
+ assert(ir->type->is_scalar() || ir->type->is_vector() ||
+ ir->type->is_sampler());
+
+ const struct gl_program *fp = &this->brw->fragment_program->Base;
+ /* Our support for uniforms is piggy-backed on the struct
+ * gl_fragment_program, because that's where the values actually
+ * get stored, rather than in some global gl_shader_program uniform
+ * store.
+ */
+ vec_values = fp->Parameters->ParameterValues[ir->location];
+ for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
+ c->prog_data.param[c->prog_data.nr_params++] = &vec_values[i];
+ }
+
+ reg = new(this->mem_ctx) fs_reg(UNIFORM, param_index);
+ }
+
+ if (!reg)
+ reg = new(this->mem_ctx) fs_reg(this, ir->type);
+
+ hash_table_insert(this->variable_ht, reg, ir);
+}
+
+void
+fs_visitor::visit(ir_dereference_variable *ir)
+{
+ fs_reg *reg = variable_storage(ir->var);
+ this->result = *reg;
+}
+
+void
+fs_visitor::visit(ir_dereference_record *ir)
+{
+ assert(!"FINISHME");
+}
+
+void
+fs_visitor::visit(ir_dereference_array *ir)
+{
+ ir_constant *index;
+ int element_size;
+
+ ir->array->accept(this);
+ index = ir->array_index->as_constant();
+
+ if (ir->type->is_matrix()) {
+ element_size = ir->type->vector_elements;
+ } else {
+ element_size = type_size(ir->type);
+ }
+
+ if (index) {
+ assert(this->result.file == UNIFORM ||
+ (this->result.file == GRF &&
+ this->result.reg != 0));
+ this->result.reg_offset += index->value.i[0] * element_size;
+ } else {
+ assert(!"FINISHME: non-constant matrix column");
+ }
+}
+
+void
+fs_visitor::visit(ir_expression *ir)
+{
+ unsigned int operand;
+ fs_reg op[2], temp;
+ fs_reg result;
+ fs_inst *inst;
+
+ for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ ir->operands[operand]->accept(this);
+ if (this->result.file == BAD_FILE) {
+ ir_print_visitor v;
+ printf("Failed to get tree for expression operand:\n");
+ ir->operands[operand]->accept(&v);
+ this->fail = true;
+ }
+ op[operand] = this->result;
+
+ /* Matrix expression operands should have been broken down to vector
+ * operations already.
+ */
+ assert(!ir->operands[operand]->type->is_matrix());
+ /* And then those vector operands should have been broken down to scalar.
+ */
+ assert(!ir->operands[operand]->type->is_vector());
+ }
+
+ /* Storage for our result. If our result goes into an assignment, it will
+ * just get copy-propagated out, so no worries.
+ */
+ this->result = fs_reg(this, ir->type);
+
+ switch (ir->operation) {
+ case ir_unop_logic_not:
+ emit(fs_inst(BRW_OPCODE_ADD, this->result, op[0], fs_reg(-1)));
+ break;
+ case ir_unop_neg:
+ op[0].negate = ~op[0].negate;
+ this->result = op[0];
+ break;
+ case ir_unop_abs:
+ op[0].abs = true;
+ this->result = op[0];
+ break;
+ case ir_unop_sign:
+ temp = fs_reg(this, ir->type);
+
+ emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(0.0f)));
+
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0.0f)));
+ inst->conditional_mod = BRW_CONDITIONAL_G;
+ inst = emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(1.0f)));
+ inst->predicated = true;
+
+ inst = emit(fs_inst(BRW_OPCODE_CMP, reg_null, op[0], fs_reg(0.0f)));
+ inst->conditional_mod = BRW_CONDITIONAL_L;
+ inst = emit(fs_inst(BRW_OPCODE_MOV, this->result, fs_reg(-1.0f)));
+ inst->predicated = true;
+
+ break;
+ case ir_unop_rcp:
+ emit(fs_inst(FS_OPCODE_RCP, this->result, op[0]));
+ break;
+
+ case ir_unop_exp2:
+ emit(fs_inst(FS_OPCODE_EXP2, this->result, op[0]));
+ break;
+ case ir_unop_log2:
+ emit(fs_inst(FS_OPCODE_LOG2, this->result, op[0]));
+ break;
+ case ir_unop_exp:
+ case ir_unop_log:
+ assert(!"not reached: should be handled by ir_explog_to_explog2");
+ break;
+ case ir_unop_sin:
+ emit(fs_inst(FS_OPCODE_SIN, this->result, op[0]));
+ break;
+ case ir_unop_cos:
+ emit(fs_inst(FS_OPCODE_COS, this->result, op[0]));
+ break;
+
+ case ir_unop_dFdx:
+ emit(fs_inst(FS_OPCODE_DDX, this->result, op[0]));
+ break;
+ case ir_unop_dFdy:
+ emit(fs_inst(FS_OPCODE_DDY, this->result, op[0]));
+ break;
+
+ case ir_binop_add:
+ emit(fs_inst(BRW_OPCODE_ADD, this->result, op[0], op[1]));
+ break;
+ case ir_binop_sub:
+ assert(!"not reached: should be handled by ir_sub_to_add_neg");
+ break;
+
+ case ir_binop_mul:
+ emit(fs_inst(BRW_OPCODE_MUL, this->result, op[0], op[1]));
+ break;
+ case ir_binop_div:
+ assert(!"not reached: should be handled by ir_div_to_mul_rcp");
+ break;
+ case ir_binop_mod:
+ assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
+ break;
+
+ case ir_binop_less:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+ inst->conditional_mod = BRW_CONDITIONAL_L;
+ emit(fs_inst(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)));
+ break;
+ case ir_binop_greater:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+ inst->conditional_mod = BRW_CONDITIONAL_G;
+ emit(fs_inst(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)));
+ break;
+ case ir_binop_lequal:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+ inst->conditional_mod = BRW_CONDITIONAL_LE;
+ emit(fs_inst(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)));
+ break;
+ case ir_binop_gequal:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+ inst->conditional_mod = BRW_CONDITIONAL_GE;
+ emit(fs_inst(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)));
+ break;
+ case ir_binop_equal:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+ inst->conditional_mod = BRW_CONDITIONAL_Z;
+ emit(fs_inst(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)));
+ break;
+ case ir_binop_nequal:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ emit(fs_inst(BRW_OPCODE_AND, this->result, this->result, fs_reg(0x1)));
+ break;
+
+ case ir_binop_logic_xor:
+ emit(fs_inst(BRW_OPCODE_XOR, this->result, op[0], op[1]));
+ break;
+
+ case ir_binop_logic_or:
+ emit(fs_inst(BRW_OPCODE_OR, this->result, op[0], op[1]));
+ break;
+
+ case ir_binop_logic_and:
+ emit(fs_inst(BRW_OPCODE_AND, this->result, op[0], op[1]));
+ break;
+
+ case ir_binop_dot:
+ case ir_binop_cross:
+ case ir_unop_any:
+ assert(!"not reached: should be handled by brw_channel_expressions");
+ break;
+
+ case ir_unop_sqrt:
+ emit(fs_inst(FS_OPCODE_SQRT, this->result, op[0]));
+ break;
+
+ case ir_unop_rsq:
+ emit(fs_inst(FS_OPCODE_RSQ, this->result, op[0]));
+ break;
+
+ case ir_unop_i2f:
+ case ir_unop_b2f:
+ case ir_unop_b2i:
+ emit(fs_inst(BRW_OPCODE_MOV, this->result, op[0]));
+ break;
+ case ir_unop_f2i:
+ emit(fs_inst(BRW_OPCODE_RNDZ, this->result, op[0]));
+ break;
+ case ir_unop_f2b:
+ case ir_unop_i2b:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], fs_reg(0.0f)));
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+ case ir_unop_trunc:
+ emit(fs_inst(BRW_OPCODE_RNDD, this->result, op[0]));
+ break;
+ case ir_unop_ceil:
+ op[0].negate = ~op[0].negate;
+ inst = emit(fs_inst(BRW_OPCODE_RNDD, this->result, op[0]));
+ this->result.negate = true;
+ break;
+ case ir_unop_floor:
+ inst = emit(fs_inst(BRW_OPCODE_RNDD, this->result, op[0]));
+ break;
+ case ir_unop_fract:
+ inst = emit(fs_inst(BRW_OPCODE_FRC, this->result, op[0]));
+ break;
+
+ case ir_binop_min:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+ inst->conditional_mod = BRW_CONDITIONAL_L;
+
+ inst = emit(fs_inst(BRW_OPCODE_SEL, this->result, op[0], op[1]));
+ inst->predicated = true;
+ break;
+ case ir_binop_max:
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, op[0], op[1]));
+ inst->conditional_mod = BRW_CONDITIONAL_G;
+
+ inst = emit(fs_inst(BRW_OPCODE_SEL, this->result, op[0], op[1]));
+ inst->predicated = true;
+ break;
+
+ case ir_binop_pow:
+ inst = emit(fs_inst(FS_OPCODE_POW, this->result, op[0], op[1]));
+ break;
+
+ case ir_unop_bit_not:
+ case ir_unop_u2f:
+ case ir_binop_lshift:
+ case ir_binop_rshift:
+ case ir_binop_bit_and:
+ case ir_binop_bit_xor:
+ case ir_binop_bit_or:
+ assert(!"GLSL 1.30 features unsupported");
+ break;
+ }
+}
+
+void
+fs_visitor::visit(ir_assignment *ir)
+{
+ struct fs_reg l, r;
+ int i;
+ int write_mask;
+ fs_inst *inst;
+
+ /* FINISHME: arrays on the lhs */
+ ir->lhs->accept(this);
+ l = this->result;
+
+ ir->rhs->accept(this);
+ r = this->result;
+
+ /* FINISHME: This should really set to the correct maximal writemask for each
+ * FINISHME: component written (in the loops below). This case can only
+ * FINISHME: occur for matrices, arrays, and structures.
+ */
+ if (ir->write_mask == 0) {
+ assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());
+ write_mask = WRITEMASK_XYZW;
+ } else {
+ assert(ir->lhs->type->is_vector() || ir->lhs->type->is_scalar());
+ write_mask = ir->write_mask;
+ }
+
+ assert(l.file != BAD_FILE);
+ assert(r.file != BAD_FILE);
+
+ if (ir->condition) {
+ /* Get the condition bool into the predicate. */
+ ir->condition->accept(this);
+ inst = emit(fs_inst(BRW_OPCODE_CMP, this->result, fs_reg(0)));
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
+ }
+
+ for (i = 0; i < type_size(ir->lhs->type); i++) {
+ if (i >= 4 || (write_mask & (1 << i))) {
+ inst = emit(fs_inst(BRW_OPCODE_MOV, l, r));
+ if (ir->condition)
+ inst->predicated = true;
+ }
+ l.reg_offset++;
+ r.reg_offset++;
+ }
+}
+
+void
+fs_visitor::visit(ir_texture *ir)
+{
+ int base_mrf = 2;
+ fs_inst *inst = NULL;
+ unsigned int mlen = 0;
+
+ ir->coordinate->accept(this);
+ fs_reg coordinate = this->result;
+
+ if (ir->projector) {
+ fs_reg inv_proj = fs_reg(this, glsl_type::float_type);
+
+ ir->projector->accept(this);
+ emit(fs_inst(FS_OPCODE_RCP, inv_proj, this->result));
+
+ fs_reg proj_coordinate = fs_reg(this, ir->coordinate->type);
+ for (unsigned int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+ emit(fs_inst(BRW_OPCODE_MUL, proj_coordinate, coordinate, inv_proj));
+ coordinate.reg_offset++;
+ proj_coordinate.reg_offset++;
+ }
+ proj_coordinate.reg_offset = 0;
+
+ coordinate = proj_coordinate;
+ }
+
+ for (mlen = 0; mlen < ir->coordinate->type->vector_elements; mlen++) {
+ emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), coordinate));
+ coordinate.reg_offset++;
+ }
+
+ /* Pre-Ironlake, the 8-wide sampler always took u,v,r. */
+ if (intel->gen < 5)
+ mlen = 3;
+
+ if (ir->shadow_comparitor) {
+ /* For shadow comparisons, we have to supply u,v,r. */
+ mlen = 3;
+
+ ir->shadow_comparitor->accept(this);
+ emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result));
+ mlen++;
+ }
+
+ /* Do we ever want to handle writemasking on texture samples? Is it
+ * performance relevant?
+ */
+ fs_reg dst = fs_reg(this, glsl_type::vec4_type);
+
+ switch (ir->op) {
+ case ir_tex:
+ inst = emit(fs_inst(FS_OPCODE_TEX, dst, fs_reg(MRF, base_mrf)));
+ break;
+ case ir_txb:
+ ir->lod_info.bias->accept(this);
+ emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result));
+ mlen++;
+
+ inst = emit(fs_inst(FS_OPCODE_TXB, dst, fs_reg(MRF, base_mrf)));
+ break;
+ case ir_txl:
+ ir->lod_info.lod->accept(this);
+ emit(fs_inst(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result));
+ mlen++;
+
+ inst = emit(fs_inst(FS_OPCODE_TXL, dst, fs_reg(MRF, base_mrf)));
+ break;
+ case ir_txd:
+ case ir_txf:
+ assert(!"GLSL 1.30 features unsupported");
+ break;
+ }
+
+ this->result = dst;
+
+ if (ir->shadow_comparitor)
+ inst->shadow_compare = true;
+ inst->mlen = mlen;
+}
+
+void
+fs_visitor::visit(ir_swizzle *ir)
+{
+ ir->val->accept(this);
+ fs_reg val = this->result;
+
+ fs_reg result = fs_reg(this, ir->type);
+ this->result = result;
+
+ for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
+ fs_reg channel = val;
+ int swiz = 0;
+
+ switch (i) {
+ case 0:
+ swiz = ir->mask.x;
+ break;
+ case 1:
+ swiz = ir->mask.y;
+ break;
+ case 2:
+ swiz = ir->mask.z;
+ break;
+ case 3:
+ swiz = ir->mask.w;
+ break;
+ }
+
+ channel.reg_offset += swiz;
+ emit(fs_inst(BRW_OPCODE_MOV, result, channel));
+ result.reg_offset++;
+ }
+}
+
+void
+fs_visitor::visit(ir_discard *ir)
+{
+ assert(ir->condition == NULL); /* FINISHME */
+
+ emit(fs_inst(FS_OPCODE_DISCARD));
+}
+
+void
+fs_visitor::visit(ir_constant *ir)
+{
+ fs_reg reg(this, ir->type);
+ this->result = reg;
+
+ for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
+ switch (ir->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ emit(fs_inst(BRW_OPCODE_MOV, reg, fs_reg(ir->value.f[i])));
+ break;
+ case GLSL_TYPE_UINT:
+ emit(fs_inst(BRW_OPCODE_MOV, reg, fs_reg(ir->value.u[i])));
+ break;
+ case GLSL_TYPE_INT:
+ emit(fs_inst(BRW_OPCODE_MOV, reg, fs_reg(ir->value.i[i])));
+ break;
+ case GLSL_TYPE_BOOL:
+ emit(fs_inst(BRW_OPCODE_MOV, reg, fs_reg((int)ir->value.b[i])));
+ break;
+ default:
+ assert(!"Non-float/uint/int/bool constant");
+ }
+ reg.reg_offset++;
+ }
+}
+
+void
+fs_visitor::visit(ir_if *ir)
+{
+ fs_inst *inst;
+
+ /* Don't point the annotation at the if statement, because then it plus
+ * the then and else blocks get printed.
+ */
+ this->base_ir = ir->condition;
+
+ /* Generate the condition into the condition code. */
+ ir->condition->accept(this);
+ inst = emit(fs_inst(BRW_OPCODE_MOV, fs_reg(brw_null_reg()), this->result));
+ inst->conditional_mod = BRW_CONDITIONAL_NZ;
+
+ inst = emit(fs_inst(BRW_OPCODE_IF));
+ inst->predicated = true;
+
+ foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ this->base_ir = ir;
+
+ ir->accept(this);
+ }
+
+ if (!ir->else_instructions.is_empty()) {
+ emit(fs_inst(BRW_OPCODE_ELSE));
+
+ foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ this->base_ir = ir;
+
+ ir->accept(this);
+ }
+ }
+
+ emit(fs_inst(BRW_OPCODE_ENDIF));
+}
+
+void
+fs_visitor::visit(ir_loop *ir)
+{
+ assert(!ir->from);
+ assert(!ir->to);
+ assert(!ir->increment);
+ assert(!ir->counter);
+
+ emit(fs_inst(BRW_OPCODE_DO));
+
+ /* Start a safety counter. If the user messed up their loop
+ * counting, we don't want to hang the GPU.
+ */
+ fs_reg max_iter = fs_reg(this, glsl_type::int_type);
+ emit(fs_inst(BRW_OPCODE_MOV, max_iter, fs_reg(10000)));
+
+ foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ fs_inst *inst;
+
+ this->base_ir = ir;
+ ir->accept(this);
+
+ /* Check the maximum loop iters counter. */
+ inst = emit(fs_inst(BRW_OPCODE_ADD, max_iter, max_iter, fs_reg(-1)));
+ inst->conditional_mod = BRW_CONDITIONAL_Z;
+
+ inst = emit(fs_inst(BRW_OPCODE_BREAK));
+ inst->predicated = true;
+ }
+
+ emit(fs_inst(BRW_OPCODE_WHILE));
+}
+
+void
+fs_visitor::visit(ir_loop_jump *ir)
+{
+ switch (ir->mode) {
+ case ir_loop_jump::jump_break:
+ emit(fs_inst(BRW_OPCODE_BREAK));
+ break;
+ case ir_loop_jump::jump_continue:
+ emit(fs_inst(BRW_OPCODE_CONTINUE));
+ break;
+ }
+}
+
+void
+fs_visitor::visit(ir_call *ir)
+{
+ assert(!"FINISHME");
+}
+
+void
+fs_visitor::visit(ir_return *ir)
+{
+ assert(!"FINISHME");
+}
+
+void
+fs_visitor::visit(ir_function *ir)
+{
+ /* Ignore function bodies other than main() -- we shouldn't see calls to
+ * them since they should all be inlined before we get to ir_to_mesa.
+ */
+ if (strcmp(ir->name, "main") == 0) {
+ const ir_function_signature *sig;
+ exec_list empty;
+
+ sig = ir->matching_signature(&empty);
+
+ assert(sig);
+
+ foreach_iter(exec_list_iterator, iter, sig->body) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ this->base_ir = ir;
+
+ ir->accept(this);
+ }
+ }
+}
+
+void
+fs_visitor::visit(ir_function_signature *ir)
+{
+ assert(!"not reached");
+ (void)ir;
+}
+
+fs_inst *
+fs_visitor::emit(fs_inst inst)
+{
+ fs_inst *list_inst = new(mem_ctx) fs_inst;
+ *list_inst = inst;
+
+ list_inst->annotation = this->current_annotation;
+ list_inst->ir = this->base_ir;
+
+ this->instructions.push_tail(list_inst);
+
+ return list_inst;
+}
+
+/** Emits a dummy fragment shader consisting of magenta for bringup purposes. */
+void
+fs_visitor::emit_dummy_fs()
+{
+ /* Everyone's favorite color. */
+ emit(fs_inst(BRW_OPCODE_MOV,
+ fs_reg(MRF, 2),
+ fs_reg(1.0f)));
+ emit(fs_inst(BRW_OPCODE_MOV,
+ fs_reg(MRF, 3),
+ fs_reg(0.0f)));
+ emit(fs_inst(BRW_OPCODE_MOV,
+ fs_reg(MRF, 4),
+ fs_reg(1.0f)));
+ emit(fs_inst(BRW_OPCODE_MOV,
+ fs_reg(MRF, 5),
+ fs_reg(0.0f)));
+
+ fs_inst *write;
+ write = emit(fs_inst(FS_OPCODE_FB_WRITE,
+ fs_reg(0),
+ fs_reg(0)));
+}
+
+/* The register location here is relative to the start of the URB
+ * data. It will get adjusted to be a real location before
+ * generate_code() time.
+ */
+struct brw_reg
+fs_visitor::interp_reg(int location, int channel)
+{
+ int regnr = location * 2 + channel / 2;
+ int stride = (channel & 1) * 4;
+
+ return brw_vec1_grf(regnr, stride);
+}
+
+/** Emits the interpolation for the varying inputs. */
+void
+fs_visitor::emit_interpolation()
+{
+ struct brw_reg g1_uw = retype(brw_vec1_grf(1, 0), BRW_REGISTER_TYPE_UW);
+ /* For now, the source regs for the setup URB data will be unset,
+ * since we don't know until codegen how many push constants we'll
+ * use, and therefore what the setup URB offset is.
+ */
+ fs_reg src_reg = reg_undef;
+
+ this->current_annotation = "compute pixel centers";
+ this->pixel_x = fs_reg(this, glsl_type::uint_type);
+ this->pixel_y = fs_reg(this, glsl_type::uint_type);
+ emit(fs_inst(BRW_OPCODE_ADD,
+ this->pixel_x,
+ fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)),
+ fs_reg(brw_imm_v(0x10101010))));
+ emit(fs_inst(BRW_OPCODE_ADD,
+ this->pixel_y,
+ fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
+ fs_reg(brw_imm_v(0x11001100))));
+
+ this->current_annotation = "compute pixel deltas from v0";
+ this->delta_x = fs_reg(this, glsl_type::float_type);
+ this->delta_y = fs_reg(this, glsl_type::float_type);
+ emit(fs_inst(BRW_OPCODE_ADD,
+ this->delta_x,
+ this->pixel_x,
+ fs_reg(negate(brw_vec1_grf(1, 0)))));
+ emit(fs_inst(BRW_OPCODE_ADD,
+ this->delta_y,
+ this->pixel_y,
+ fs_reg(brw_vec1_grf(1, 1))));
+
+ this->current_annotation = "compute pos.w and 1/pos.w";
+ /* Compute wpos. Unlike many other varying inputs, we usually need it
+ * to produce 1/w, and the varying variable wouldn't show up.
+ */
+ fs_reg wpos = fs_reg(this, glsl_type::vec4_type);
+ this->interp_attrs[FRAG_ATTRIB_WPOS] = wpos;
+ emit(fs_inst(BRW_OPCODE_MOV, wpos, this->pixel_x)); /* FINISHME: ARB_fcc */
+ wpos.reg_offset++;
+ emit(fs_inst(BRW_OPCODE_MOV, wpos, this->pixel_y)); /* FINISHME: ARB_fcc */
+ wpos.reg_offset++;
+ emit(fs_inst(FS_OPCODE_LINTERP, wpos, this->delta_x, this->delta_y,
+ interp_reg(FRAG_ATTRIB_WPOS, 2)));
+ wpos.reg_offset++;
+ emit(fs_inst(FS_OPCODE_LINTERP, wpos, this->delta_x, this->delta_y,
+ interp_reg(FRAG_ATTRIB_WPOS, 3)));
+ /* Compute the pixel W value from wpos.w. */
+ this->pixel_w = fs_reg(this, glsl_type::float_type);
+ emit(fs_inst(FS_OPCODE_RCP, this->pixel_w, wpos));
+
+ /* FINISHME: gl_FrontFacing */
+
+ foreach_iter(exec_list_iterator, iter, *this->shader->ir) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_variable *var = ir->as_variable();
+
+ if (!var)
+ continue;
+
+ if (var->mode != ir_var_in)
+ continue;
+
+ /* If it's already set up (WPOS), skip. */
+ if (var->location == 0)
+ continue;
+
+ this->current_annotation = talloc_asprintf(this->mem_ctx,
+ "interpolate %s "
+ "(FRAG_ATTRIB[%d])",
+ var->name,
+ var->location);
+ emit_pinterp(var->location);
+ }
+ this->current_annotation = NULL;
+}
+
+void
+fs_visitor::emit_pinterp(int location)
+{
+ fs_reg interp_attr = fs_reg(this, glsl_type::vec4_type);
+ this->interp_attrs[location] = interp_attr;
+
+ for (unsigned int i = 0; i < 4; i++) {
+ struct brw_reg interp = interp_reg(location, i);
+ emit(fs_inst(FS_OPCODE_LINTERP,
+ interp_attr,
+ this->delta_x,
+ this->delta_y,
+ fs_reg(interp)));
+ interp_attr.reg_offset++;
+ }
+ interp_attr.reg_offset -= 4;
+
+ for (unsigned int i = 0; i < 4; i++) {
+ emit(fs_inst(BRW_OPCODE_MUL,
+ interp_attr,
+ interp_attr,
+ this->pixel_w));
+ interp_attr.reg_offset++;
+ }
+}
+
+void
+fs_visitor::emit_fb_writes()
+{
+ this->current_annotation = "FB write";
+
+ assert(this->frag_color || !"FINISHME: MRT");
+ fs_reg color = *(variable_storage(this->frag_color));
+
+ for (int i = 0; i < 4; i++) {
+ emit(fs_inst(BRW_OPCODE_MOV,
+ fs_reg(MRF, 2 + i),
+ color));
+ color.reg_offset++;
+ }
+
+ emit(fs_inst(FS_OPCODE_FB_WRITE,
+ fs_reg(0),
+ fs_reg(0)));
+
+ this->current_annotation = NULL;
+}
+
+void
+fs_visitor::generate_fb_write(fs_inst *inst)
+{
+ GLboolean eot = 1; /* FINISHME: MRT */
+ /* FINISHME: AADS */
+
+ /* Header is 2 regs, g0 and g1 are the contents. g0 will be implied
+ * move, here's g1.
+ */
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+ brw_MOV(p,
+ brw_message_reg(1),
+ brw_vec8_grf(1, 0));
+ brw_pop_insn_state(p);
+
+ int nr = 2 + 4;
+
+ brw_fb_WRITE(p,
+ 8, /* dispatch_width */
+ retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW),
+ 0, /* base MRF */
+ retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
+ 0, /* FINISHME: MRT target */
+ nr,
+ 0,
+ eot);
+}
+
+void
+fs_visitor::generate_linterp(fs_inst *inst,
+ struct brw_reg dst, struct brw_reg *src)
+{
+ struct brw_reg delta_x = src[0];
+ struct brw_reg delta_y = src[1];
+ struct brw_reg interp = src[2];
+
+ if (brw->has_pln &&
+ delta_y.nr == delta_x.nr + 1 &&
+ (intel->gen >= 6 || (delta_x.nr & 1) == 0)) {
+ brw_PLN(p, dst, interp, delta_x);
+ } else {
+ brw_LINE(p, brw_null_reg(), interp, delta_x);
+ brw_MAC(p, dst, suboffset(interp, 1), delta_y);
+ }
+}
+
+void
+fs_visitor::generate_math(fs_inst *inst,
+ struct brw_reg dst, struct brw_reg *src)
+{
+ int op;
+
+ switch (inst->opcode) {
+ case FS_OPCODE_RCP:
+ op = BRW_MATH_FUNCTION_INV;
+ break;
+ case FS_OPCODE_RSQ:
+ op = BRW_MATH_FUNCTION_RSQ;
+ break;
+ case FS_OPCODE_SQRT:
+ op = BRW_MATH_FUNCTION_SQRT;
+ break;
+ case FS_OPCODE_EXP2:
+ op = BRW_MATH_FUNCTION_EXP;
+ break;
+ case FS_OPCODE_LOG2:
+ op = BRW_MATH_FUNCTION_LOG;
+ break;
+ case FS_OPCODE_POW:
+ op = BRW_MATH_FUNCTION_POW;
+ break;
+ case FS_OPCODE_SIN:
+ op = BRW_MATH_FUNCTION_SIN;
+ break;
+ case FS_OPCODE_COS:
+ op = BRW_MATH_FUNCTION_COS;
+ break;
+ default:
+ assert(!"not reached: unknown math function");
+ op = 0;
+ break;
+ }
+
+ if (inst->opcode == FS_OPCODE_POW) {
+ brw_MOV(p, brw_message_reg(3), src[1]);
+ }
+
+ brw_math(p, dst,
+ op,
+ inst->saturate ? BRW_MATH_SATURATE_SATURATE :
+ BRW_MATH_SATURATE_NONE,
+ 2, src[0],
+ BRW_MATH_DATA_VECTOR,
+ BRW_MATH_PRECISION_FULL);
+}
+
+void
+fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
+{
+ int msg_type = -1;
+ int rlen = 4;
+
+ if (intel->gen == 5) {
+ switch (inst->opcode) {
+ case FS_OPCODE_TEX:
+ if (inst->shadow_compare) {
+ msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_COMPARE_GEN5;
+ } else {
+ msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_GEN5;
+ }
+ break;
+ case FS_OPCODE_TXB:
+ if (inst->shadow_compare) {
+ msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE_GEN5;
+ } else {
+ msg_type = BRW_SAMPLER_MESSAGE_SAMPLE_BIAS_GEN5;
+ }
+ break;
+ }
+ } else {
+ switch (inst->opcode) {
+ case FS_OPCODE_TEX:
+ /* Note that G45 and older determines shadow compare and dispatch width
+ * from message length for most messages.
+ */
+ if (inst->shadow_compare) {
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
+ } else {
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
+ }
+ case FS_OPCODE_TXB:
+ if (inst->shadow_compare) {
+ assert(!"FINISHME: shadow compare with bias.");
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+ } else {
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
+ rlen = 8;
+ }
+ break;
+ }
+ }
+ assert(msg_type != -1);
+
+ /* g0 header. */
+ src.nr--;
+
+ brw_SAMPLE(p,
+ retype(dst, BRW_REGISTER_TYPE_UW),
+ src.nr,
+ retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
+ SURF_INDEX_TEXTURE(inst->sampler),
+ inst->sampler,
+ WRITEMASK_XYZW,
+ msg_type,
+ rlen,
+ inst->mlen + 1,
+ 0,
+ 1,
+ BRW_SAMPLER_SIMD_MODE_SIMD8);
+}
+
+void
+fs_visitor::generate_discard(fs_inst *inst)
+{
+ struct brw_reg g0 = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); /* IMASK */
+ brw_AND(p, g0, c->emit_mask_reg, g0);
+ brw_pop_insn_state(p);
+}
+
+static void
+trivial_assign_reg(int header_size, fs_reg *reg)
+{
+ if (reg->file == GRF && reg->reg != 0) {
+ reg->hw_reg = header_size + reg->reg - 1 + reg->reg_offset;
+ reg->reg = 0;
+ }
+}
+
+void
+fs_visitor::assign_curb_setup()
+{
+ c->prog_data.first_curbe_grf = c->key.nr_payload_regs;
+ c->prog_data.curb_read_length = ALIGN(c->prog_data.nr_params, 8) / 8;
+
+ /* Map the offsets in the UNIFORM file to fixed HW regs. */
+ foreach_iter(exec_list_iterator, iter, this->instructions) {
+ fs_inst *inst = (fs_inst *)iter.get();
+
+ for (unsigned int i = 0; i < 3; i++) {
+ if (inst->src[i].file == UNIFORM) {
+ int constant_nr = inst->src[i].hw_reg + inst->src[i].reg_offset;
+ struct brw_reg brw_reg = brw_vec1_grf(c->prog_data.first_curbe_grf +
+ constant_nr / 8,
+ constant_nr % 8);
+
+ inst->src[i].file = FIXED_HW_REG;
+ inst->src[i].fixed_hw_reg = brw_reg;
+ }
+ }
+ }
+}
+
+void
+fs_visitor::assign_urb_setup()
+{
+ int urb_start = c->prog_data.first_curbe_grf + c->prog_data.curb_read_length;
+ int interp_reg_nr[FRAG_ATTRIB_MAX];
+
+ c->prog_data.urb_read_length = 0;
+
+ /* Figure out where each of the incoming setup attributes lands. */
+ for (unsigned int i = 0; i < FRAG_ATTRIB_MAX; i++) {
+ interp_reg_nr[i] = -1;
+
+ if (i != FRAG_ATTRIB_WPOS &&
+ !(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(i)))
+ continue;
+
+ /* Each attribute is 4 setup channels, each of which is half a reg. */
+ interp_reg_nr[i] = urb_start + c->prog_data.urb_read_length;
+ c->prog_data.urb_read_length += 2;
+ }
+
+ /* Map the register numbers for FS_OPCODE_LINTERP so that it uses
+ * the correct setup input.
+ */
+ foreach_iter(exec_list_iterator, iter, this->instructions) {
+ fs_inst *inst = (fs_inst *)iter.get();
+
+ if (inst->opcode != FS_OPCODE_LINTERP)
+ continue;
+
+ assert(inst->src[2].file == FIXED_HW_REG);
+
+ int location = inst->src[2].fixed_hw_reg.nr / 2;
+ assert(interp_reg_nr[location] != -1);
+ inst->src[2].fixed_hw_reg.nr = (interp_reg_nr[location] +
+ (inst->src[2].fixed_hw_reg.nr & 1));
+ }
+
+ this->first_non_payload_grf = urb_start + c->prog_data.urb_read_length;
+}
+
+void
+fs_visitor::assign_regs()
+{
+ int header_size = this->first_non_payload_grf;
+ int last_grf = 0;
+
+ /* FINISHME: trivial assignment of register numbers */
+ foreach_iter(exec_list_iterator, iter, this->instructions) {
+ fs_inst *inst = (fs_inst *)iter.get();
+
+ trivial_assign_reg(header_size, &inst->dst);
+ trivial_assign_reg(header_size, &inst->src[0]);
+ trivial_assign_reg(header_size, &inst->src[1]);
+
+ last_grf = MAX2(last_grf, inst->dst.hw_reg);
+ last_grf = MAX2(last_grf, inst->src[0].hw_reg);
+ last_grf = MAX2(last_grf, inst->src[1].hw_reg);
+ }
+
+ this->grf_used = last_grf + 1;
+}
+
+static struct brw_reg brw_reg_from_fs_reg(fs_reg *reg)
+{
+ struct brw_reg brw_reg;
+
+ switch (reg->file) {
+ case GRF:
+ case ARF:
+ case MRF:
+ brw_reg = brw_vec8_reg(reg->file,
+ reg->hw_reg, 0);
+ brw_reg = retype(brw_reg, reg->type);
+ break;
+ case IMM:
+ switch (reg->type) {
+ case BRW_REGISTER_TYPE_F:
+ brw_reg = brw_imm_f(reg->imm.f);
+ break;
+ case BRW_REGISTER_TYPE_D:
+ brw_reg = brw_imm_d(reg->imm.i);
+ break;
+ case BRW_REGISTER_TYPE_UD:
+ brw_reg = brw_imm_ud(reg->imm.u);
+ break;
+ default:
+ assert(!"not reached");
+ break;
+ }
+ break;
+ case FIXED_HW_REG:
+ brw_reg = reg->fixed_hw_reg;
+ break;
+ case BAD_FILE:
+ /* Probably unused. */
+ brw_reg = brw_null_reg();
+ break;
+ case UNIFORM:
+ assert(!"not reached");
+ brw_reg = brw_null_reg();
+ break;
+ }
+ if (reg->abs)
+ brw_reg = brw_abs(brw_reg);
+ if (reg->negate)
+ brw_reg = negate(brw_reg);
+
+ return brw_reg;
+}
+
+void
+fs_visitor::generate_code()
+{
+ unsigned int annotation_len = 0;
+ int last_native_inst = 0;
+ struct brw_instruction *if_stack[16], *loop_stack[16];
+ int if_stack_depth = 0, loop_stack_depth = 0;
+ int if_depth_in_loop[16];
+
+ if_depth_in_loop[loop_stack_depth] = 0;
+
+ memset(&if_stack, 0, sizeof(if_stack));
+ foreach_iter(exec_list_iterator, iter, this->instructions) {
+ fs_inst *inst = (fs_inst *)iter.get();
+ struct brw_reg src[3], dst;
+
+ for (unsigned int i = 0; i < 3; i++) {
+ src[i] = brw_reg_from_fs_reg(&inst->src[i]);
+ }
+ dst = brw_reg_from_fs_reg(&inst->dst);
+
+ brw_set_conditionalmod(p, inst->conditional_mod);
+ brw_set_predicate_control(p, inst->predicated);
+
+ switch (inst->opcode) {
+ case BRW_OPCODE_MOV:
+ brw_MOV(p, dst, src[0]);
+ break;
+ case BRW_OPCODE_ADD:
+ brw_ADD(p, dst, src[0], src[1]);
+ break;
+ case BRW_OPCODE_MUL:
+ brw_MUL(p, dst, src[0], src[1]);
+ break;
+
+ case BRW_OPCODE_FRC:
+ brw_FRC(p, dst, src[0]);
+ break;
+ case BRW_OPCODE_RNDD:
+ brw_RNDD(p, dst, src[0]);
+ break;
+ case BRW_OPCODE_RNDZ:
+ brw_RNDZ(p, dst, src[0]);
+ break;
+
+ case BRW_OPCODE_AND:
+ brw_AND(p, dst, src[0], src[1]);
+ break;
+ case BRW_OPCODE_OR:
+ brw_OR(p, dst, src[0], src[1]);
+ break;
+ case BRW_OPCODE_XOR:
+ brw_XOR(p, dst, src[0], src[1]);
+ break;
+
+ case BRW_OPCODE_CMP:
+ brw_CMP(p, dst, inst->conditional_mod, src[0], src[1]);
+ break;
+ case BRW_OPCODE_SEL:
+ brw_SEL(p, dst, src[0], src[1]);
+ break;
+
+ case BRW_OPCODE_IF:
+ assert(if_stack_depth < 16);
+ if_stack[if_stack_depth] = brw_IF(p, BRW_EXECUTE_8);
+ if_stack_depth++;
+ break;
+ case BRW_OPCODE_ELSE:
+ if_stack[if_stack_depth - 1] =
+ brw_ELSE(p, if_stack[if_stack_depth - 1]);
+ break;
+ case BRW_OPCODE_ENDIF:
+ if_stack_depth--;
+ brw_ENDIF(p , if_stack[if_stack_depth]);
+ break;
+
+ case BRW_OPCODE_DO:
+ loop_stack[loop_stack_depth++] = brw_DO(p, BRW_EXECUTE_8);
+ if_depth_in_loop[loop_stack_depth] = 0;
+ break;
+
+ case BRW_OPCODE_BREAK:
+ brw_BREAK(p, if_depth_in_loop[loop_stack_depth]);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ break;
+ case BRW_OPCODE_CONTINUE:
+ brw_CONT(p, if_depth_in_loop[loop_stack_depth]);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ break;
+
+ case BRW_OPCODE_WHILE: {
+ struct brw_instruction *inst0, *inst1;
+ GLuint br = 1;
+
+ if (intel->gen == 5)
+ br = 2;
+
+ assert(loop_stack_depth > 0);
+ loop_stack_depth--;
+ inst0 = inst1 = brw_WHILE(p, loop_stack[loop_stack_depth]);
+ /* patch all the BREAK/CONT instructions from last BGNLOOP */
+ while (inst0 > loop_stack[loop_stack_depth]) {
+ inst0--;
+ if (inst0->header.opcode == BRW_OPCODE_BREAK &&
+ inst0->bits3.if_else.jump_count == 0) {
+ inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
+ }
+ else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
+ inst0->bits3.if_else.jump_count == 0) {
+ inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
+ }
+ }
+ }
+ break;
+
+ case FS_OPCODE_RCP:
+ case FS_OPCODE_RSQ:
+ case FS_OPCODE_SQRT:
+ case FS_OPCODE_EXP2:
+ case FS_OPCODE_LOG2:
+ case FS_OPCODE_POW:
+ case FS_OPCODE_SIN:
+ case FS_OPCODE_COS:
+ generate_math(inst, dst, src);
+ break;
+ case FS_OPCODE_LINTERP:
+ generate_linterp(inst, dst, src);
+ break;
+ case FS_OPCODE_TEX:
+ case FS_OPCODE_TXB:
+ case FS_OPCODE_TXL:
+ generate_tex(inst, dst, src[0]);
+ break;
+ case FS_OPCODE_DISCARD:
+ generate_discard(inst);
+ break;
+ case FS_OPCODE_FB_WRITE:
+ generate_fb_write(inst);
+ break;
+ default:
+ if (inst->opcode < (int)ARRAY_SIZE(brw_opcodes)) {
+ _mesa_problem(ctx, "Unsupported opcode `%s' in FS",
+ brw_opcodes[inst->opcode].name);
+ } else {
+ _mesa_problem(ctx, "Unsupported opcode %d in FS", inst->opcode);
+ }
+ this->fail = true;
+ }
+
+ if (annotation_len < p->nr_insn) {
+ annotation_len *= 2;
+ if (annotation_len < 16)
+ annotation_len = 16;
+
+ this->annotation_string = talloc_realloc(this->mem_ctx,
+ annotation_string,
+ const char *,
+ annotation_len);
+ this->annotation_ir = talloc_realloc(this->mem_ctx,
+ annotation_ir,
+ ir_instruction *,
+ annotation_len);
+ }
+
+ for (unsigned int i = last_native_inst; i < p->nr_insn; i++) {
+ this->annotation_string[i] = inst->annotation;
+ this->annotation_ir[i] = inst->ir;
+ }
+ last_native_inst = p->nr_insn;
+ }
+}
+
+GLboolean
+brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
+{
+ struct brw_compile *p = &c->func;
+ struct intel_context *intel = &brw->intel;
+ GLcontext *ctx = &intel->ctx;
+ struct brw_shader *shader = NULL;
+ struct gl_shader_program *prog = ctx->Shader.CurrentProgram;
+
+ if (!prog)
+ return GL_FALSE;
+
+ if (!using_new_fs)
+ return GL_FALSE;
+
+ for (unsigned int i = 0; i < prog->_NumLinkedShaders; i++) {
+ if (prog->_LinkedShaders[i]->Type == GL_FRAGMENT_SHADER) {
+ shader = (struct brw_shader *)prog->_LinkedShaders[i];
+ break;
+ }
+ }
+ if (!shader)
+ return GL_FALSE;
+
+ /* We always use 8-wide mode, at least for now. For one, flow
+ * control only works in 8-wide. Also, when we're fragment shader
+ * bound, we're almost always under register pressure as well, so
+ * 8-wide would save us from the performance cliff of spilling
+ * regs.
+ */
+ c->dispatch_width = 8;
+
+ if (INTEL_DEBUG & DEBUG_WM) {
+ printf("GLSL IR for native fragment shader %d:\n", prog->Name);
+ _mesa_print_ir(shader->ir, NULL);
+ printf("\n");
+ }
+
+ /* Now the main event: Visit the shader IR and generate our FS IR for it.
+ */
+ fs_visitor v(c, shader);
+
+ if (0) {
+ v.emit_dummy_fs();
+ } else {
+ v.emit_interpolation();
+
+ /* Generate FS IR for main(). (the visitor only descends into
+ * functions called "main").
+ */
+ foreach_iter(exec_list_iterator, iter, *shader->ir) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ v.base_ir = ir;
+ ir->accept(&v);
+ }
+
+ if (v.fail)
+ return GL_FALSE;
+
+ v.emit_fb_writes();
+ v.assign_curb_setup();
+ v.assign_urb_setup();
+ v.assign_regs();
+ }
+
+ v.generate_code();
+
+ if (INTEL_DEBUG & DEBUG_WM) {
+ const char *last_annotation_string = NULL;
+ ir_instruction *last_annotation_ir = NULL;
+
+ printf("Native code for fragment shader %d:\n", prog->Name);
+ for (unsigned int i = 0; i < p->nr_insn; i++) {
+ if (last_annotation_ir != v.annotation_ir[i]) {
+ last_annotation_ir = v.annotation_ir[i];
+ if (last_annotation_ir) {
+ printf(" ");
+ last_annotation_ir->print();
+ printf("\n");
+ }
+ }
+ if (last_annotation_string != v.annotation_string[i]) {
+ last_annotation_string = v.annotation_string[i];
+ if (last_annotation_string)
+ printf(" %s\n", last_annotation_string);
+ }
+ brw_disasm(stdout, &p->store[i], intel->gen);
+ }
+ printf("\n");
+ }
+
+ c->prog_data.total_grf = v.grf_used;
+ c->prog_data.total_scratch = 0;
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
new file mode 100644
index 00000000000..d8d58a9467b
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
@@ -0,0 +1,365 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 brw_wm_channel_expressions.cpp
+ *
+ * Breaks vector operations down into operations on each component.
+ *
+ * The 965 fragment shader receives 8 or 16 pixels at a time, so each
+ * channel of a vector is laid out as 1 or 2 8-float registers. Each
+ * ALU operation operates on one of those channel registers. As a
+ * result, there is no value to the 965 fragment shader in tracking
+ * "vector" expressions in the sense of GLSL fragment shaders, when
+ * doing a channel at a time may help in constant folding, algebraic
+ * simplification, and reducing the liveness of channel registers.
+ *
+ * The exception to the desire to break everything down to floats is
+ * texturing. The texture sampler returns a writemasked masked
+ * 4/8-register sequence containing the texture values. We don't want
+ * to dispatch to the sampler separately for each channel we need, so
+ * we do retain the vector types in that case.
+ */
+
+extern "C" {
+#include "main/core.h"
+#include "brw_wm.h"
+}
+#include "../glsl/ir.h"
+#include "../glsl/ir_expression_flattening.h"
+#include "../glsl/glsl_types.h"
+
+class ir_channel_expressions_visitor : public ir_hierarchical_visitor {
+public:
+ ir_channel_expressions_visitor()
+ {
+ this->progress = false;
+ this->mem_ctx = NULL;
+ }
+
+ ir_visitor_status visit_leave(ir_assignment *);
+
+ ir_rvalue *get_element(ir_variable *var, unsigned int element);
+ void assign(ir_assignment *ir, int elem, ir_rvalue *val);
+
+ bool progress;
+ void *mem_ctx;
+};
+
+static bool
+channel_expressions_predicate(ir_instruction *ir)
+{
+ ir_expression *expr = ir->as_expression();
+ unsigned int i;
+
+ if (!expr)
+ return false;
+
+ for (i = 0; i < expr->get_num_operands(); i++) {
+ if (expr->operands[i]->type->is_vector())
+ return true;
+ }
+
+ return false;
+}
+
+extern "C" {
+GLboolean
+brw_do_channel_expressions(exec_list *instructions)
+{
+ ir_channel_expressions_visitor v;
+
+ /* Pull out any matrix expression to a separate assignment to a
+ * temp. This will make our handling of the breakdown to
+ * operations on the matrix's vector components much easier.
+ */
+ do_expression_flattening(instructions, channel_expressions_predicate);
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
+}
+
+ir_rvalue *
+ir_channel_expressions_visitor::get_element(ir_variable *var, unsigned int elem)
+{
+ ir_dereference *deref;
+
+ if (var->type->is_scalar())
+ return new(mem_ctx) ir_dereference_variable(var);
+
+ assert(elem < var->type->components());
+ deref = new(mem_ctx) ir_dereference_variable(var);
+ return new(mem_ctx) ir_swizzle(deref, elem, 0, 0, 0, 1);
+}
+
+void
+ir_channel_expressions_visitor::assign(ir_assignment *ir, int elem, ir_rvalue *val)
+{
+ ir_dereference *lhs = ir->lhs->clone(mem_ctx, NULL);
+ ir_assignment *assign;
+ ir_swizzle *val_swiz;
+
+ /* This assign-of-expression should have been generated by the
+ * expression flattening visitor (since we never short circit to
+ * not flatten, even for plain assignments of variables), so the
+ * writemask is always full.
+ */
+ assert(ir->write_mask == (1 << ir->lhs->type->components()) - 1);
+
+ /* Smear the float across all the channels for the masked write. */
+ val_swiz = new(mem_ctx) ir_swizzle(val, 0, 0, 0, 0,
+ ir->lhs->type->components());
+ assign = new(mem_ctx) ir_assignment(lhs, val_swiz, NULL, (1 << elem));
+ ir->insert_before(assign);
+}
+
+ir_visitor_status
+ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
+{
+ ir_expression *expr = ir->rhs->as_expression();
+ bool found_vector = false;
+ unsigned int i, vector_elements = 1;
+ ir_variable *op_var[2];
+
+ if (!expr)
+ return visit_continue;
+
+ if (!this->mem_ctx)
+ this->mem_ctx = talloc_parent(ir);
+
+ for (i = 0; i < expr->get_num_operands(); i++) {
+ if (expr->operands[i]->type->is_vector()) {
+ found_vector = true;
+ vector_elements = expr->operands[i]->type->vector_elements;
+ break;
+ }
+ }
+ if (!found_vector)
+ return visit_continue;
+
+ /* Store the expression operands in temps so we can use them
+ * multiple times.
+ */
+ for (i = 0; i < expr->get_num_operands(); i++) {
+ ir_assignment *assign;
+ ir_dereference *deref;
+
+ assert(!expr->operands[i]->type->is_matrix());
+
+ op_var[i] = new(mem_ctx) ir_variable(expr->operands[i]->type,
+ "channel_expressions",
+ ir_var_temporary);
+ ir->insert_before(op_var[i]);
+
+ deref = new(mem_ctx) ir_dereference_variable(op_var[i]);
+ assign = new(mem_ctx) ir_assignment(deref,
+ expr->operands[i],
+ NULL);
+ ir->insert_before(assign);
+ }
+
+ const glsl_type *element_type = glsl_type::get_instance(ir->lhs->type->base_type,
+ 1, 1);
+
+ /* OK, time to break down this vector operation. */
+ switch (expr->operation) {
+ case ir_unop_bit_not:
+ case ir_unop_logic_not:
+ case ir_unop_neg:
+ case ir_unop_abs:
+ case ir_unop_sign:
+ case ir_unop_rcp:
+ case ir_unop_rsq:
+ case ir_unop_sqrt:
+ case ir_unop_exp:
+ case ir_unop_log:
+ case ir_unop_exp2:
+ case ir_unop_log2:
+ case ir_unop_f2i:
+ case ir_unop_i2f:
+ case ir_unop_f2b:
+ case ir_unop_b2f:
+ case ir_unop_i2b:
+ case ir_unop_b2i:
+ case ir_unop_u2f:
+ case ir_unop_trunc:
+ case ir_unop_ceil:
+ case ir_unop_floor:
+ case ir_unop_fract:
+ case ir_unop_sin:
+ case ir_unop_cos:
+ case ir_unop_dFdx:
+ case ir_unop_dFdy:
+ for (i = 0; i < vector_elements; i++) {
+ ir_rvalue *op0 = get_element(op_var[0], i);
+
+ assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
+ element_type,
+ op0,
+ NULL));
+ }
+ break;
+
+ case ir_binop_add:
+ case ir_binop_sub:
+ case ir_binop_mul:
+ case ir_binop_div:
+ case ir_binop_mod:
+ case ir_binop_min:
+ case ir_binop_max:
+ case ir_binop_pow:
+ case ir_binop_lshift:
+ case ir_binop_rshift:
+ case ir_binop_bit_and:
+ case ir_binop_bit_xor:
+ case ir_binop_bit_or:
+ for (i = 0; i < vector_elements; i++) {
+ ir_rvalue *op0 = get_element(op_var[0], i);
+ ir_rvalue *op1 = get_element(op_var[1], i);
+
+ assign(ir, i, new(mem_ctx) ir_expression(expr->operation,
+ element_type,
+ op0,
+ op1));
+ }
+ break;
+
+ case ir_unop_any: {
+ ir_expression *temp;
+ temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
+ element_type,
+ get_element(op_var[0], 0),
+ get_element(op_var[0], 1));
+
+ for (i = 2; i < vector_elements; i++) {
+ temp = new(mem_ctx) ir_expression(ir_binop_logic_or,
+ element_type,
+ get_element(op_var[0], i),
+ temp);
+ }
+ assign(ir, 0, temp);
+ break;
+ }
+
+ case ir_binop_dot: {
+ ir_expression *last = NULL;
+ for (i = 0; i < vector_elements; i++) {
+ ir_rvalue *op0 = get_element(op_var[0], i);
+ ir_rvalue *op1 = get_element(op_var[1], i);
+ ir_expression *temp;
+
+ temp = new(mem_ctx) ir_expression(ir_binop_mul,
+ element_type,
+ op0,
+ op1);
+ if (last) {
+ last = new(mem_ctx) ir_expression(ir_binop_add,
+ element_type,
+ temp,
+ last);
+ } else {
+ last = temp;
+ }
+ }
+ assign(ir, 0, last);
+ break;
+ }
+
+ case ir_binop_cross: {
+ for (i = 0; i < vector_elements; i++) {
+ int swiz0 = (i + 1) % 3;
+ int swiz1 = (i + 2) % 3;
+ ir_expression *temp1, *temp2;
+
+ temp1 = new(mem_ctx) ir_expression(ir_binop_mul,
+ element_type,
+ get_element(op_var[0], swiz0),
+ get_element(op_var[1], swiz1));
+
+ temp2 = new(mem_ctx) ir_expression(ir_binop_mul,
+ element_type,
+ get_element(op_var[1], swiz0),
+ get_element(op_var[0], swiz1));
+
+ temp2 = new(mem_ctx) ir_expression(ir_unop_neg,
+ element_type,
+ temp2,
+ NULL);
+
+ assign(ir, i, new(mem_ctx) ir_expression(ir_binop_add,
+ element_type,
+ temp1, temp2));
+ }
+ break;
+ }
+
+ case ir_binop_less:
+ case ir_binop_greater:
+ case ir_binop_lequal:
+ case ir_binop_gequal:
+ case ir_binop_logic_and:
+ case ir_binop_logic_xor:
+ case ir_binop_logic_or:
+ ir->print();
+ printf("\n");
+ assert(!"not reached: expression operates on scalars only");
+ break;
+ case ir_binop_equal:
+ case ir_binop_nequal: {
+ ir_expression *last = NULL;
+ for (i = 0; i < vector_elements; i++) {
+ ir_rvalue *op0 = get_element(op_var[0], i);
+ ir_rvalue *op1 = get_element(op_var[1], i);
+ ir_expression *temp;
+ ir_expression_operation join;
+
+ if (expr->operation == ir_binop_equal)
+ join = ir_binop_logic_and;
+ else
+ join = ir_binop_logic_or;
+
+ temp = new(mem_ctx) ir_expression(expr->operation,
+ element_type,
+ op0,
+ op1);
+ if (last) {
+ last = new(mem_ctx) ir_expression(join,
+ element_type,
+ temp,
+ last);
+ } else {
+ last = temp;
+ }
+ }
+ assign(ir, 0, last);
+ break;
+ }
+ }
+
+ ir->remove();
+ this->progress = true;
+
+ return visit_continue;
+}
diff --git a/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp b/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp
new file mode 100644
index 00000000000..00d5c202485
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp
@@ -0,0 +1,391 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 brw_wm_vector_splitting.cpp
+ *
+ * If a vector is only ever referenced by its components, then
+ * split those components out to individual variables so they can be
+ * handled normally by other optimization passes.
+ *
+ * This skips vectors in uniforms and varyings, which need to be
+ * accessible as vectors for their access by the GL. Also, vector
+ * results of non-variable-derefs in assignments aren't handled
+ * because to do so we would have to store the vector result to a
+ * temporary in order to unload each channel, and to do so would just
+ * loop us back to where we started. For the 965, this is exactly the
+ * behavior we want for the results of texture lookups, but probably not for
+ */
+
+extern "C" {
+#include "main/core.h"
+#include "intel_context.h"
+}
+#include "../glsl/ir.h"
+#include "../glsl/ir_visitor.h"
+#include "../glsl/ir_print_visitor.h"
+#include "../glsl/ir_rvalue_visitor.h"
+#include "../glsl/glsl_types.h"
+
+static bool debug = false;
+
+class variable_entry : public exec_node
+{
+public:
+ variable_entry(ir_variable *var)
+ {
+ this->var = var;
+ this->whole_vector_access = 0;
+ this->declaration = false;
+ this->mem_ctx = NULL;
+ }
+
+ ir_variable *var; /* The key: the variable's pointer. */
+
+ /** Number of times the variable is referenced, including assignments. */
+ unsigned whole_vector_access;
+
+ bool declaration; /* If the variable had a decl in the instruction stream */
+
+ ir_variable *components[4];
+
+ /** talloc_parent(this->var) -- the shader's talloc context. */
+ void *mem_ctx;
+};
+
+class ir_vector_reference_visitor : public ir_hierarchical_visitor {
+public:
+ ir_vector_reference_visitor(void)
+ {
+ this->mem_ctx = talloc_new(NULL);
+ this->variable_list.make_empty();
+ }
+
+ ~ir_vector_reference_visitor(void)
+ {
+ talloc_free(mem_ctx);
+ }
+
+ virtual ir_visitor_status visit(ir_variable *);
+ virtual ir_visitor_status visit(ir_dereference_variable *);
+ virtual ir_visitor_status visit_enter(ir_swizzle *);
+ virtual ir_visitor_status visit_enter(ir_assignment *);
+ virtual ir_visitor_status visit_enter(ir_function_signature *);
+
+ variable_entry *get_variable_entry(ir_variable *var);
+
+ /* List of variable_entry */
+ exec_list variable_list;
+
+ void *mem_ctx;
+};
+
+variable_entry *
+ir_vector_reference_visitor::get_variable_entry(ir_variable *var)
+{
+ assert(var);
+
+ if (!var->type->is_vector())
+ return NULL;
+
+ switch (var->mode) {
+ case ir_var_uniform:
+ case ir_var_in:
+ case ir_var_out:
+ case ir_var_inout:
+ /* Can't split varyings or uniforms. Function in/outs won't get split
+ * either, so don't care about the ambiguity.
+ */
+ return NULL;
+ case ir_var_auto:
+ case ir_var_temporary:
+ break;
+ }
+
+ foreach_iter(exec_list_iterator, iter, this->variable_list) {
+ variable_entry *entry = (variable_entry *)iter.get();
+ if (entry->var == var)
+ return entry;
+ }
+
+ variable_entry *entry = new(mem_ctx) variable_entry(var);
+ this->variable_list.push_tail(entry);
+ return entry;
+}
+
+
+ir_visitor_status
+ir_vector_reference_visitor::visit(ir_variable *ir)
+{
+ variable_entry *entry = this->get_variable_entry(ir);
+
+ if (entry)
+ entry->declaration = true;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vector_reference_visitor::visit(ir_dereference_variable *ir)
+{
+ ir_variable *const var = ir->var;
+ variable_entry *entry = this->get_variable_entry(var);
+
+ if (entry)
+ entry->whole_vector_access++;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vector_reference_visitor::visit_enter(ir_swizzle *ir)
+{
+ /* Don't descend into a vector ir_dereference_variable below. */
+ if (ir->val->as_dereference_variable() && ir->type->is_scalar())
+ return visit_continue_with_parent;
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vector_reference_visitor::visit_enter(ir_assignment *ir)
+{
+ if (ir->lhs->as_dereference_variable() &&
+ ir->rhs->as_dereference_variable() &&
+ !ir->condition) {
+ /* We'll split copies of a vector to copies of channels, so don't
+ * descend to the ir_dereference_variables.
+ */
+ return visit_continue_with_parent;
+ }
+ if (ir->lhs->as_dereference_variable() &&
+ is_power_of_two(ir->write_mask) &&
+ !ir->condition) {
+ /* If we're writing just a channel, then channel-splitting the LHS is OK.
+ */
+ ir->rhs->accept(this);
+ return visit_continue_with_parent;
+ }
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_vector_reference_visitor::visit_enter(ir_function_signature *ir)
+{
+ /* We don't want to descend into the function parameters and
+ * split them, so just accept the body here.
+ */
+ visit_list_elements(this, &ir->body);
+ return visit_continue_with_parent;
+}
+
+class ir_vector_splitting_visitor : public ir_rvalue_visitor {
+public:
+ ir_vector_splitting_visitor(exec_list *vars)
+ {
+ this->variable_list = vars;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_assignment *);
+
+ void handle_rvalue(ir_rvalue **rvalue);
+ struct variable_entry *get_splitting_entry(ir_variable *var);
+
+ exec_list *variable_list;
+ void *mem_ctx;
+};
+
+struct variable_entry *
+ir_vector_splitting_visitor::get_splitting_entry(ir_variable *var)
+{
+ assert(var);
+
+ if (!var->type->is_vector())
+ return NULL;
+
+ foreach_iter(exec_list_iterator, iter, *this->variable_list) {
+ variable_entry *entry = (variable_entry *)iter.get();
+ if (entry->var == var) {
+ return entry;
+ }
+ }
+
+ return NULL;
+}
+
+void
+ir_vector_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ ir_swizzle *swiz = (*rvalue)->as_swizzle();
+ if (!swiz || !swiz->type->is_scalar())
+ return;
+
+ ir_dereference_variable *deref_var = swiz->val->as_dereference_variable();
+ if (!deref_var)
+ return;
+
+ variable_entry *entry = get_splitting_entry(deref_var->var);
+ if (!entry)
+ return;
+
+ ir_variable *var = entry->components[swiz->mask.x];
+ *rvalue = new(entry->mem_ctx) ir_dereference_variable(var);
+}
+
+ir_visitor_status
+ir_vector_splitting_visitor::visit_leave(ir_assignment *ir)
+{
+ ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable();
+ ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable();
+ variable_entry *lhs = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL;
+ variable_entry *rhs = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL;
+
+ if (lhs_deref && rhs_deref && (lhs || rhs) && !ir->condition) {
+ /* Straight assignment of vector variables. */
+ for (unsigned int i = 0; i < ir->rhs->type->vector_elements; i++) {
+ ir_dereference *new_lhs;
+ ir_rvalue *new_rhs;
+ void *mem_ctx = lhs ? lhs->mem_ctx : rhs->mem_ctx;
+ unsigned int writemask;
+
+ if (lhs) {
+ new_lhs = new(mem_ctx) ir_dereference_variable(lhs->components[i]);
+ writemask = (ir->write_mask >> i) & 1;
+ } else {
+ new_lhs = ir->lhs->clone(mem_ctx, NULL);
+ writemask = ir->write_mask & (1 << i);
+ }
+
+ if (rhs) {
+ new_rhs = new(mem_ctx) ir_dereference_variable(rhs->components[i]);
+ /* If we're writing into a writemask, smear it out to that channel. */
+ if (!lhs)
+ new_rhs = new(mem_ctx) ir_swizzle(new_rhs, i, i, i, i, i + 1);
+ } else {
+ new_rhs = new(mem_ctx) ir_swizzle(ir->rhs->clone(mem_ctx, NULL),
+ i, i, i, i, 1);
+ }
+
+ ir->insert_before(new(mem_ctx) ir_assignment(new_lhs,
+ new_rhs,
+ NULL, writemask));
+ }
+ ir->remove();
+ } else if (lhs) {
+ int elem = -1;
+
+ switch (ir->write_mask) {
+ case (1 << 0):
+ elem = 0;
+ break;
+ case (1 << 1):
+ elem = 1;
+ break;
+ case (1 << 2):
+ elem = 2;
+ break;
+ case (1 << 3):
+ elem = 3;
+ break;
+ default:
+ ir->print();
+ assert(!"not reached: non-channelwise dereference of LHS.");
+ }
+
+ ir->lhs = new(mem_ctx) ir_dereference_variable(lhs->components[elem]);
+ ir->write_mask = (1 << 0);
+
+ handle_rvalue(&ir->rhs);
+ ir->rhs = new(mem_ctx) ir_swizzle(ir->rhs,
+ elem, elem, elem, elem, 1);
+ } else {
+ handle_rvalue(&ir->rhs);
+ }
+
+ handle_rvalue(&ir->condition);
+
+ return visit_continue;
+}
+
+extern "C" {
+bool
+brw_do_vector_splitting(exec_list *instructions)
+{
+ ir_vector_reference_visitor refs;
+
+ visit_list_elements(&refs, instructions);
+
+ /* Trim out variables we can't split. */
+ foreach_iter(exec_list_iterator, iter, refs.variable_list) {
+ variable_entry *entry = (variable_entry *)iter.get();
+
+ if (debug) {
+ printf("vector %s@%p: decl %d, whole_access %d\n",
+ entry->var->name, (void *) entry->var, entry->declaration,
+ entry->whole_vector_access);
+ }
+
+ if (!entry->declaration || entry->whole_vector_access) {
+ entry->remove();
+ }
+ }
+
+ if (refs.variable_list.is_empty())
+ return false;
+
+ void *mem_ctx = talloc_new(NULL);
+
+ /* Replace the decls of the vectors to be split with their split
+ * components.
+ */
+ foreach_iter(exec_list_iterator, iter, refs.variable_list) {
+ variable_entry *entry = (variable_entry *)iter.get();
+ const struct glsl_type *type;
+ type = glsl_type::get_instance(entry->var->type->base_type, 1, 1);
+
+ entry->mem_ctx = talloc_parent(entry->var);
+
+ for (unsigned int i = 0; i < entry->var->type->vector_elements; i++) {
+ const char *name = talloc_asprintf(mem_ctx, "%s_%c",
+ entry->var->name,
+ "xyzw"[i]);
+
+ entry->components[i] = new(entry->mem_ctx) ir_variable(type, name,
+ ir_var_temporary);
+ entry->var->insert_before(entry->components[i]);
+ }
+
+ entry->var->remove();
+ }
+
+ ir_vector_splitting_visitor split(&refs.variable_list);
+ visit_list_elements(&split, instructions);
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+}
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 572175f463e..6eeaba77720 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -281,7 +281,7 @@ static void emit_depthbuffer(struct brw_context *brw)
}
assert(region->tiling != I915_TILING_X);
- if (IS_GEN6(intel->intelScreen->deviceID))
+ if (intel->gen >= 6)
assert(region->tiling != I915_TILING_NONE);
BEGIN_BATCH(len);
@@ -295,7 +295,7 @@ static void emit_depthbuffer(struct brw_context *brw)
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
0);
OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
- ((region->pitch - 1) << 6) |
+ ((region->width - 1) << 6) |
((region->height - 1) << 19));
OUT_BATCH(0);
diff --git a/src/mesa/drivers/dri/i965/brw_optimize.c b/src/mesa/drivers/dri/i965/brw_optimize.c
index 8aa6fb6cc6f..cbed2bd5cb1 100644
--- a/src/mesa/drivers/dri/i965/brw_optimize.c
+++ b/src/mesa/drivers/dri/i965/brw_optimize.c
@@ -32,12 +32,7 @@
#include "brw_defines.h"
#include "brw_eu.h"
-static const struct {
- char *name;
- int nsrc;
- int ndst;
- GLboolean is_arith;
-} inst_opcode[128] = {
+const struct brw_instruction_info brw_opcodes[128] = {
[BRW_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1, .is_arith = 1 },
[BRW_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1, .is_arith = 1 },
[BRW_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1, .is_arith = 1 },
@@ -94,7 +89,7 @@ static const struct {
static INLINE
GLboolean brw_is_arithmetic_inst(const struct brw_instruction *inst)
{
- return inst_opcode[inst->header.opcode].is_arith;
+ return brw_opcodes[inst->header.opcode].is_arith;
}
static const GLuint inst_stride[7] = {
@@ -122,7 +117,7 @@ brw_is_grf_written(const struct brw_instruction *inst,
int reg_index, int size,
int gen)
{
- if (inst_opcode[inst->header.opcode].ndst == 0)
+ if (brw_opcodes[inst->header.opcode].ndst == 0)
return GL_FALSE;
if (inst->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT)
@@ -161,20 +156,19 @@ brw_is_grf_written(const struct brw_instruction *inst,
return left < right;
}
-/* Specific path for message register since we need to handle the compr4 case */
-static INLINE GLboolean
-brw_is_mrf_written(const struct brw_instruction *inst, int reg_index, int size)
+static GLboolean
+brw_is_mrf_written_alu(const struct brw_instruction *inst,
+ int reg_index, int size)
{
- if (inst_opcode[inst->header.opcode].ndst == 0)
+ if (brw_opcodes[inst->header.opcode].ndst == 0)
return GL_FALSE;
- if (inst->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT)
- if (inst->bits1.ia1.dest_reg_file == BRW_MESSAGE_REGISTER_FILE)
- return GL_TRUE;
-
if (inst->bits1.da1.dest_reg_file != BRW_MESSAGE_REGISTER_FILE)
return GL_FALSE;
+ if (inst->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT)
+ return GL_TRUE;
+
const int reg_start = reg_index * REG_SIZE;
const int reg_end = reg_start + size;
@@ -188,8 +182,6 @@ brw_is_mrf_written(const struct brw_instruction *inst, int reg_index, int size)
if (is_compr4 && inst->header.execution_size != BRW_EXECUTE_16)
return GL_TRUE;
- GLboolean is_written = GL_FALSE;
-
/* Here we write mrf_{i} and mrf_{i+4}. So we read two times 8 elements */
if (is_compr4) {
const int length = 8 * type_size * inst->bits1.da1.dest_horiz_stride;
@@ -210,7 +202,8 @@ brw_is_mrf_written(const struct brw_instruction *inst, int reg_index, int size)
const int left1 = MAX2(write_start1, reg_start);
const int right1 = MIN2(write_end1, reg_end);
- is_written = left0 < right0 || left1 < right1;
+ if (left0 < right0 || left1 < right1)
+ return GL_TRUE;
}
else {
int length;
@@ -223,25 +216,41 @@ brw_is_mrf_written(const struct brw_instruction *inst, int reg_index, int size)
+ inst->bits1.da1.dest_subreg_nr;
const int write_end = write_start + length;
const int left = MAX2(write_start, reg_start);
- const int right = MIN2(write_end, reg_end);;
+ const int right = MIN2(write_end, reg_end);
- is_written = left < right;
+ if (left < right)
+ return GL_TRUE;
}
- /* SEND may perform an implicit mov to a mrf register */
- if (is_written == GL_FALSE &&
- inst->header.opcode == BRW_OPCODE_SEND &&
- inst->bits1.da1.src0_reg_file != 0) {
+ return GL_FALSE;
+}
- const int mrf_start = inst->header.destreg__conditionalmod;
- const int write_start = mrf_start * REG_SIZE;
- const int write_end = write_start + REG_SIZE;
- const int left = MAX2(write_start, reg_start);
- const int right = MIN2(write_end, reg_end);;
- is_written = left < right;
- }
+/* SEND may perform an implicit mov to a mrf register */
+static GLboolean brw_is_mrf_written_send(const struct brw_instruction *inst,
+ int reg_index, int size)
+{
+
+ const int reg_start = reg_index * REG_SIZE;
+ const int reg_end = reg_start + size;
+ const int mrf_start = inst->header.destreg__conditionalmod;
+ const int write_start = mrf_start * REG_SIZE;
+ const int write_end = write_start + REG_SIZE;
+ const int left = MAX2(write_start, reg_start);
+ const int right = MIN2(write_end, reg_end);
+
+ if (inst->header.opcode != BRW_OPCODE_SEND ||
+ inst->bits1.da1.src0_reg_file == 0)
+ return GL_FALSE;
- return is_written;
+ return left < right;
+}
+
+/* Specific path for message register since we need to handle the compr4 case */
+static INLINE GLboolean
+brw_is_mrf_written(const struct brw_instruction *inst, int reg_index, int size)
+{
+ return (brw_is_mrf_written_alu(inst, reg_index, size) ||
+ brw_is_mrf_written_send(inst, reg_index, size));
}
static INLINE GLboolean
@@ -284,7 +293,7 @@ static INLINE GLboolean
brw_is_grf_read(const struct brw_instruction *inst, int reg_index, int size)
{
int i, j;
- if (inst_opcode[inst->header.opcode].nsrc == 0)
+ if (brw_opcodes[inst->header.opcode].nsrc == 0)
return GL_FALSE;
/* Look at first source. We must take into account register regions to
@@ -292,7 +301,7 @@ brw_is_grf_read(const struct brw_instruction *inst, int reg_index, int size)
* since we do not take into account the fact that some complete registers
* may be skipped
*/
- if (inst_opcode[inst->header.opcode].nsrc >= 1) {
+ if (brw_opcodes[inst->header.opcode].nsrc >= 1) {
if (inst->bits2.da1.src0_address_mode != BRW_ADDRESS_DIRECT)
if (inst->bits1.ia1.src0_reg_file == BRW_GENERAL_REGISTER_FILE)
@@ -327,7 +336,7 @@ brw_is_grf_read(const struct brw_instruction *inst, int reg_index, int size)
}
/* Second src register */
- if (inst_opcode[inst->header.opcode].nsrc >= 2) {
+ if (brw_opcodes[inst->header.opcode].nsrc >= 2) {
if (inst->bits3.da1.src1_address_mode != BRW_ADDRESS_DIRECT)
if (inst->bits1.ia1.src1_reg_file == BRW_GENERAL_REGISTER_FILE)
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index 4b08d2599bc..bc152204a42 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -36,6 +36,7 @@
#include "program/program.h"
#include "program/programopt.h"
#include "tnl/tnl.h"
+#include "talloc.h"
#include "brw_context.h"
#include "brw_wm.h"
@@ -114,10 +115,7 @@ shader_error(GLcontext *ctx, struct gl_program *prog, const char *msg)
shader = _mesa_lookup_shader_program(ctx, prog->Id);
if (shader) {
- if (shader->InfoLog) {
- free(shader->InfoLog);
- }
- shader->InfoLog = _mesa_strdup(msg);
+ shader->InfoLog = talloc_strdup_append(shader->InfoLog, msg);
shader->LinkStatus = GL_FALSE;
}
}
@@ -170,6 +168,9 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx,
* See piglit glsl-{vs,fs}-functions-[23] tests.
*/
for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = prog->Instructions + i;
+ int r;
+
if (prog->Instructions[i].Opcode == OPCODE_CAL) {
shader_error(ctx, prog,
"i965 driver doesn't yet support uninlined function "
@@ -177,16 +178,28 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx,
"the end of the function to work around it.\n");
return GL_FALSE;
}
- if (prog->Instructions[i].DstReg.RelAddr &&
- prog->Instructions[i].DstReg.File == PROGRAM_INPUT) {
+
+ if (prog->Instructions[i].Opcode == OPCODE_RET) {
shader_error(ctx, prog,
- "Variable indexing of shader inputs unsupported\n");
+ "i965 driver doesn't yet support \"return\" "
+ "from main().\n");
return GL_FALSE;
}
- if (prog->Instructions[i].DstReg.RelAddr &&
+
+ for (r = 0; r < _mesa_num_inst_src_regs(inst->Opcode); r++) {
+ if (prog->Instructions[i].SrcReg[r].RelAddr &&
+ prog->Instructions[i].SrcReg[r].File == PROGRAM_INPUT) {
+ shader_error(ctx, prog,
+ "Variable indexing of shader inputs unsupported\n");
+ return GL_FALSE;
+ }
+ }
+
+ if (target == GL_FRAGMENT_PROGRAM_ARB &&
+ prog->Instructions[i].DstReg.RelAddr &&
prog->Instructions[i].DstReg.File == PROGRAM_OUTPUT) {
shader_error(ctx, prog,
- "Variable indexing of shader outputs unsupported\n");
+ "Variable indexing of FS outputs unsupported\n");
return GL_FALSE;
}
if (target == GL_FRAGMENT_PROGRAM_ARB) {
@@ -218,5 +231,10 @@ void brwInitFragProgFuncs( struct dd_function_table *functions )
functions->DeleteProgram = brwDeleteProgram;
functions->IsProgramNative = brwIsProgramNative;
functions->ProgramStringNotify = brwProgramStringNotify;
+
+ functions->NewShader = brw_new_shader;
+ functions->NewShaderProgram = brw_new_shader_program;
+ functions->CompileShader = brw_compile_shader;
+ functions->LinkShader = brw_link_shader;
}
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index af08446f2d8..c5d296b1295 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -107,6 +107,7 @@ extern const struct brw_tracked_state gen6_sf_vp;
extern const struct brw_tracked_state gen6_urb;
extern const struct brw_tracked_state gen6_viewport_state;
extern const struct brw_tracked_state gen6_vs_state;
+extern const struct brw_tracked_state gen6_wm_constants;
extern const struct brw_tracked_state gen6_wm_state;
/***********************************************************************
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index f92a19c2aa0..a0c130557e3 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -35,7 +35,6 @@
#include "brw_state.h"
#include "intel_batchbuffer.h"
#include "intel_buffers.h"
-#include "intel_chipset.h"
/* This is used to initialize brw->state.atoms[]. We could use this
* list directly except for a single atom, brw_constant_buffer, which
@@ -129,7 +128,7 @@ const struct brw_tracked_state *gen6_atoms[] =
&gen6_cc_state_pointers,
&brw_vs_constants, /* Before vs_surfaces and constant_buffer */
- &brw_wm_constants, /* Before wm_surfaces and constant_buffer */
+ &gen6_wm_constants, /* Before wm_surfaces and constant_buffer */
&brw_vs_surfaces, /* must do before unit */
&brw_wm_constant_surface, /* must do before wm surfaces/bind bo */
@@ -351,7 +350,7 @@ void brw_validate_state( struct brw_context *brw )
brw_add_validated_bo(brw, intel->batch->buf);
- if (IS_GEN6(intel->intelScreen->deviceID)) {
+ if (intel->gen >= 6) {
atoms = gen6_atoms;
num_atoms = ARRAY_SIZE(gen6_atoms);
} else {
@@ -425,7 +424,7 @@ void brw_upload_state(struct brw_context *brw)
const struct brw_tracked_state **atoms;
int num_atoms;
- if (IS_GEN6(intel->intelScreen->deviceID)) {
+ if (intel->gen >= 6) {
atoms = gen6_atoms;
num_atoms = ARRAY_SIZE(gen6_atoms);
} else {
diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h
index 2fde42a7060..2a118e01c53 100644
--- a/src/mesa/drivers/dri/i965/brw_structs.h
+++ b/src/mesa/drivers/dri/i965/brw_structs.h
@@ -750,7 +750,7 @@ struct gen6_depth_stencil_state
} ds1;
struct {
- GLuint pad0:25;
+ GLuint pad0:26;
GLuint depth_write_enable:1;
GLuint depth_test_func:3;
GLuint pad1:1;
@@ -1305,13 +1305,14 @@ struct brw_instruction
GLuint access_mode:1;
GLuint mask_control:1;
GLuint dependency_control:2;
- GLuint compression_control:2;
+ GLuint compression_control:2; /* gen6: quater control */
GLuint thread_control:2;
GLuint predicate_control:4;
GLuint predicate_inverse:1;
GLuint execution_size:3;
GLuint destreg__conditionalmod:4; /* destreg - send, conditionalmod - others */
- GLuint pad0:2;
+ GLuint acc_wr_control:1;
+ GLuint cmpt_control:1;
GLuint debug_control:1;
GLuint saturate:1;
} header;
@@ -1359,7 +1360,7 @@ struct brw_instruction
GLuint dest_writemask:4;
GLuint dest_subreg_nr:1;
GLuint dest_reg_nr:8;
- GLuint pad1:2;
+ GLuint dest_horiz_stride:2;
GLuint dest_address_mode:1;
} da16;
@@ -1373,7 +1374,7 @@ struct brw_instruction
GLuint dest_writemask:4;
GLint dest_indirect_offset:6;
GLuint dest_subreg_nr:3;
- GLuint pad1:2;
+ GLuint dest_horiz_stride:2;
GLuint dest_address_mode:1;
} ia16;
} bits1;
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 9a832af9a97..9f90e1e5e5c 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -75,10 +75,10 @@ static void do_vs_prog( struct brw_context *brw,
c.prog_data.outputs_written |= BITFIELD64_BIT(VERT_RESULT_TEX0 + i);
}
- if (0)
- _mesa_print_program(&c.vp->program.Base);
-
-
+ if (0) {
+ _mesa_fprint_program_opt(stdout, &c.vp->program.Base, PROG_PRINT_DEBUG,
+ GL_TRUE);
+ }
/* Emit GEN4 code.
*/
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index b6b558e9a69..1d88c6b5a46 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -47,6 +47,7 @@ brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg)
[OPCODE_MOV] = 1,
[OPCODE_ADD] = 2,
[OPCODE_CMP] = 3,
+ [OPCODE_DP2] = 2,
[OPCODE_DP3] = 2,
[OPCODE_DP4] = 2,
[OPCODE_DPH] = 2,
@@ -97,6 +98,39 @@ static void release_tmps( struct brw_vs_compile *c )
c->last_tmp = c->first_tmp;
}
+static int
+get_first_reladdr_output(struct gl_vertex_program *vp)
+{
+ int i;
+ int first_reladdr_output = VERT_RESULT_MAX;
+
+ for (i = 0; i < vp->Base.NumInstructions; i++) {
+ struct prog_instruction *inst = vp->Base.Instructions + i;
+
+ if (inst->DstReg.File == PROGRAM_OUTPUT &&
+ inst->DstReg.RelAddr &&
+ inst->DstReg.Index < first_reladdr_output)
+ first_reladdr_output = inst->DstReg.Index;
+ }
+
+ return first_reladdr_output;
+}
+
+/* Clears the record of which vp_const_buffer elements have been
+ * loaded into our constant buffer registers, for the starts of new
+ * blocks after control flow.
+ */
+static void
+clear_current_const(struct brw_vs_compile *c)
+{
+ unsigned int i;
+
+ if (c->vp->use_const_buffer) {
+ for (i = 0; i < 3; i++) {
+ c->current_const[i].index = -1;
+ }
+ }
+}
/**
* Preallocate GRF register before code emit.
@@ -108,6 +142,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
struct intel_context *intel = &c->func.brw->intel;
GLuint i, reg = 0, mrf;
int attributes_in_vue;
+ int first_reladdr_output;
/* Determine whether to use a real constant buffer or use a block
* of GRF registers for constants. The later is faster but only
@@ -225,6 +260,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
else
mrf = 4;
+ first_reladdr_output = get_first_reladdr_output(&c->vp->program);
for (i = 0; i < VERT_RESULT_MAX; i++) {
if (c->prog_data.outputs_written & BITFIELD64_BIT(i)) {
c->nr_outputs++;
@@ -253,15 +289,16 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
* For attributes beyond the compute-to-MRF, we compute to
* GRFs and they will be written in the second URB_WRITE.
*/
- if (mrf < 15) {
+ if (first_reladdr_output > i && mrf < 15) {
c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf);
mrf++;
}
else {
- if (!c->first_overflow_output)
+ if (mrf >= 15 && !c->first_overflow_output)
c->first_overflow_output = i;
c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
reg++;
+ mrf++;
}
}
}
@@ -292,10 +329,10 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
if (c->vp->use_const_buffer) {
for (i = 0; i < 3; i++) {
- c->current_const[i].index = -1;
c->current_const[i].reg = brw_vec8_grf(reg, 0);
reg++;
}
+ clear_current_const(c);
}
for (i = 0; i < 128; i++) {
@@ -502,6 +539,23 @@ static void emit_cmp( struct brw_compile *p,
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
}
+static void emit_sign(struct brw_vs_compile *c,
+ struct brw_reg dst,
+ struct brw_reg arg0)
+{
+ struct brw_compile *p = &c->func;
+
+ brw_MOV(p, dst, brw_imm_f(0));
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, brw_imm_f(0));
+ brw_MOV(p, dst, brw_imm_f(-1.0));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, arg0, brw_imm_f(0));
+ brw_MOV(p, dst, brw_imm_f(1.0));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+}
+
static void emit_max( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
@@ -1010,13 +1064,11 @@ move_to_reladdr_dst(struct brw_vs_compile *c,
int reg_size = 32;
struct brw_reg addr_reg = c->regs[PROGRAM_ADDRESS][0];
struct brw_reg vp_address = retype(vec1(addr_reg), BRW_REGISTER_TYPE_D);
- struct brw_reg temp_base = c->regs[inst->DstReg.File][0];
- GLuint byte_offset = temp_base.nr * 32 + temp_base.subnr;
+ struct brw_reg base = c->regs[inst->DstReg.File][inst->DstReg.Index];
+ GLuint byte_offset = base.nr * 32 + base.subnr;
struct brw_reg indirect = brw_vec4_indirect(0,0);
struct brw_reg acc = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UW);
- byte_offset += inst->DstReg.Index * reg_size;
-
brw_push_insn_state(p);
brw_set_access_mode(p, BRW_ALIGN_1);
@@ -1162,10 +1214,12 @@ static struct brw_reg get_arg( struct brw_vs_compile *c,
/* Convert 3-bit swizzle to 2-bit.
*/
- reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src->Swizzle, 0),
- GET_SWZ(src->Swizzle, 1),
- GET_SWZ(src->Swizzle, 2),
- GET_SWZ(src->Swizzle, 3));
+ if (reg.file != BRW_IMMEDIATE_VALUE) {
+ reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src->Swizzle, 0),
+ GET_SWZ(src->Swizzle, 1),
+ GET_SWZ(src->Swizzle, 2),
+ GET_SWZ(src->Swizzle, 3));
+ }
/* Note this is ok for non-swizzle instructions:
*/
@@ -1211,6 +1265,7 @@ static struct brw_reg get_dst( struct brw_vs_compile *c,
reg = brw_null_reg();
}
+ assert(reg.type != BRW_IMMEDIATE_VALUE);
reg.dw1.bits.writemask = dst.WriteMask;
return reg;
@@ -1299,6 +1354,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
struct brw_reg ndc;
int eot;
GLuint len_vertex_header = 2;
+ int next_mrf, i;
if (c->key.copy_edgeflag) {
brw_MOV(p,
@@ -1376,6 +1432,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
* of zeros followed by two sets of NDC coordinates:
*/
brw_set_access_mode(p, BRW_ALIGN_1);
+ brw_set_acc_write_control(p, 0);
/* The VUE layout is documented in Volume 2a. */
if (intel->gen >= 6) {
@@ -1416,6 +1473,23 @@ static void emit_vertex_write( struct brw_vs_compile *c)
len_vertex_header = 2;
}
+ /* Move variable-addressed, non-overflow outputs to their MRFs. */
+ next_mrf = 2 + len_vertex_header;
+ for (i = 0; i < VERT_RESULT_MAX; i++) {
+ if (c->first_overflow_output > 0 && i >= c->first_overflow_output)
+ break;
+ if (!(c->prog_data.outputs_written & BITFIELD64_BIT(i)))
+ continue;
+
+ if (i >= VERT_RESULT_TEX0 &&
+ c->regs[PROGRAM_OUTPUT][i].file == BRW_GENERAL_REGISTER_FILE) {
+ brw_MOV(p, brw_message_reg(next_mrf), c->regs[PROGRAM_OUTPUT][i]);
+ next_mrf++;
+ } else if (c->regs[PROGRAM_OUTPUT][i].file == BRW_MESSAGE_REGISTER_FILE) {
+ next_mrf = c->regs[PROGRAM_OUTPUT][i].nr + 1;
+ }
+ }
+
eot = (c->first_overflow_output == 0);
brw_urb_WRITE(p,
@@ -1541,18 +1615,23 @@ void brw_vs_emit(struct brw_vs_compile *c )
const GLuint nr_insns = c->vp->program.Base.NumInstructions;
GLuint insn, if_depth = 0, loop_depth = 0;
struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH] = { 0 };
+ int if_depth_in_loop[MAX_LOOP_DEPTH];
const struct brw_indirect stack_index = brw_indirect(0, 0);
GLuint index;
GLuint file;
if (INTEL_DEBUG & DEBUG_VS) {
printf("vs-mesa:\n");
- _mesa_print_program(&c->vp->program.Base);
+ _mesa_fprint_program_opt(stdout, &c->vp->program.Base, PROG_PRINT_DEBUG,
+ GL_TRUE);
printf("\n");
}
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_set_access_mode(p, BRW_ALIGN_16);
+ if_depth_in_loop[loop_depth] = 0;
+
+ brw_set_acc_write_control(p, 1);
for (insn = 0; insn < nr_insns; insn++) {
GLuint i;
@@ -1591,7 +1670,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
const struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
struct brw_reg args[3], dst;
GLuint i;
-
+
#if 0
printf("%d: ", insn);
_mesa_print_instruction(inst);
@@ -1636,6 +1715,9 @@ void brw_vs_emit(struct brw_vs_compile *c )
case OPCODE_COS:
emit_math1(c, BRW_MATH_FUNCTION_COS, dst, args[0], BRW_MATH_PRECISION_FULL);
break;
+ case OPCODE_DP2:
+ brw_DP2(p, dst, args[0], args[1]);
+ break;
case OPCODE_DP3:
brw_DP3(p, dst, args[0], args[1]);
break;
@@ -1732,6 +1814,9 @@ void brw_vs_emit(struct brw_vs_compile *c )
case OPCODE_SLE:
unalias2(c, dst, args[0], args[1], emit_sle);
break;
+ case OPCODE_SSG:
+ unalias1(c, dst, args[0], emit_sign);
+ break;
case OPCODE_SUB:
brw_ADD(p, dst, args[0], negate(args[1]));
break;
@@ -1753,31 +1838,38 @@ void brw_vs_emit(struct brw_vs_compile *c )
if_inst[if_depth] = brw_IF(p, BRW_EXECUTE_8);
/* Note that brw_IF smashes the predicate_control field. */
if_inst[if_depth]->header.predicate_control = get_predicate(inst);
+ if_depth_in_loop[loop_depth]++;
if_depth++;
break;
case OPCODE_ELSE:
+ clear_current_const(c);
assert(if_depth > 0);
if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]);
break;
case OPCODE_ENDIF:
+ clear_current_const(c);
assert(if_depth > 0);
brw_ENDIF(p, if_inst[--if_depth]);
+ if_depth_in_loop[loop_depth]--;
break;
case OPCODE_BGNLOOP:
+ clear_current_const(c);
loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
+ if_depth_in_loop[loop_depth] = 0;
break;
case OPCODE_BRK:
brw_set_predicate_control(p, get_predicate(inst));
- brw_BREAK(p);
+ brw_BREAK(p, if_depth_in_loop[loop_depth]);
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
case OPCODE_CONT:
brw_set_predicate_control(p, get_predicate(inst));
- brw_CONT(p);
+ brw_CONT(p, if_depth_in_loop[loop_depth]);
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
case OPCODE_ENDLOOP:
{
+ clear_current_const(c);
struct brw_instruction *inst0, *inst1;
GLuint br = 1;
@@ -1793,12 +1885,10 @@ void brw_vs_emit(struct brw_vs_compile *c )
if (inst0->header.opcode == BRW_OPCODE_BREAK &&
inst0->bits3.if_else.jump_count == 0) {
inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
- inst0->bits3.if_else.pop_count = 0;
}
else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
inst0->bits3.if_else.jump_count == 0) {
inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
- inst0->bits3.if_else.pop_count = 0;
}
}
}
@@ -1883,11 +1973,9 @@ void brw_vs_emit(struct brw_vs_compile *c )
}
}
- if (inst->DstReg.RelAddr && inst->DstReg.File == PROGRAM_TEMPORARY) {
- /* We don't do RelAddr of PROGRAM_OUTPUT yet, because of the
- * compute-to-mrf and the fact that we are allocating
- * registers for only the used PROGRAM_OUTPUTs.
- */
+ if (inst->DstReg.RelAddr) {
+ assert(inst->DstReg.File == PROGRAM_TEMPORARY||
+ inst->DstReg.File == PROGRAM_OUTPUT);
move_to_reladdr_dst(c, inst, dst);
}
@@ -1903,7 +1991,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
printf("vs-native:\n");
for (i = 0; i < p->nr_insn; i++)
- brw_disasm(stderr, &p->store[i], intel->gen);
+ brw_disasm(stdout, &p->store[i], intel->gen);
printf("\n");
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index 14227a51332..8f1601d10f1 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -101,6 +101,7 @@ static void brw_destroy_context( struct intel_context *intel )
dri_bo_release(&brw->wm.prog_bo);
dri_bo_release(&brw->wm.state_bo);
dri_bo_release(&brw->wm.const_bo);
+ dri_bo_release(&brw->wm.push_const_bo);
dri_bo_release(&brw->cc.prog_bo);
dri_bo_release(&brw->cc.state_bo);
dri_bo_release(&brw->cc.vp_bo);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index e182fc32029..d70be7bda28 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -32,7 +32,7 @@
#include "brw_context.h"
#include "brw_wm.h"
#include "brw_state.h"
-
+#include "main/formats.h"
/** Return number of src args for given instruction */
GLuint brw_wm_nr_args( GLuint opcode )
@@ -68,6 +68,7 @@ GLuint brw_wm_is_scalar_result( GLuint opcode )
case OPCODE_RCP:
case OPCODE_RSQ:
case OPCODE_SIN:
+ case OPCODE_DP2:
case OPCODE_DP3:
case OPCODE_DP4:
case OPCODE_DPH:
@@ -177,17 +178,19 @@ static void do_wm_prog( struct brw_context *brw,
/* temporary sanity check assertion */
ASSERT(fp->isGLSL == brw_wm_is_glsl(&c->fp->program));
- /*
- * Shader which use GLSL features such as flow control are handled
- * differently from "simple" shaders.
- */
- if (fp->isGLSL) {
- c->dispatch_width = 8;
- brw_wm_glsl_emit(brw, c);
- }
- else {
- c->dispatch_width = 16;
- brw_wm_non_glsl_emit(brw, c);
+ if (!brw_wm_fs_emit(brw, c)) {
+ /*
+ * Shader which use GLSL features such as flow control are handled
+ * differently from "simple" shaders.
+ */
+ if (fp->isGLSL) {
+ c->dispatch_width = 8;
+ brw_wm_glsl_emit(brw, c);
+ }
+ else {
+ c->dispatch_width = 16;
+ brw_wm_non_glsl_emit(brw, c);
+ }
}
if (INTEL_DEBUG & DEBUG_WM)
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index f40977fab8d..2639d4f26b3 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -61,7 +61,7 @@ struct brw_wm_prog_key {
GLuint source_depth_reg:3;
GLuint aa_dest_stencil_reg:3;
GLuint dest_depth_reg:3;
- GLuint nr_depth_regs:3;
+ GLuint nr_payload_regs:4;
GLuint computes_depth:1; /* could be derived from program string */
GLuint source_depth_to_render_target:1;
GLuint flat_shade:1;
@@ -306,6 +306,7 @@ void brw_wm_lookup_iz( GLuint line_aa,
GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp);
void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c);
+GLboolean brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c);
/* brw_wm_emit.c */
void emit_alu1(struct brw_compile *p,
@@ -343,6 +344,11 @@ void emit_delta_xy(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0);
+void emit_dp2(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1);
void emit_dp3(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
@@ -425,6 +431,10 @@ void emit_sop(struct brw_compile *p,
GLuint cond,
const struct brw_reg *arg0,
const struct brw_reg *arg1);
+void emit_sign(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0);
void emit_tex(struct brw_wm_compile *c,
struct brw_reg *dst,
GLuint dst_flags,
@@ -450,4 +460,13 @@ void emit_xpd(struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1);
+GLboolean brw_compile_shader(GLcontext *ctx,
+ struct gl_shader *shader);
+GLboolean brw_link_shader(GLcontext *ctx, struct gl_shader_program *prog);
+struct gl_shader *brw_new_shader(GLcontext *ctx, GLuint name, GLuint type);
+struct gl_shader_program *brw_new_shader_program(GLcontext *ctx, GLuint name);
+
+GLboolean brw_do_channel_expressions(struct exec_list *instructions);
+GLboolean brw_do_vector_splitting(struct exec_list *instructions);
+
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_wm_debug.c b/src/mesa/drivers/dri/i965/brw_wm_debug.c
index a78cc8b54e5..6a91251a80e 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_debug.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_debug.c
@@ -44,16 +44,16 @@ void brw_wm_print_value( struct brw_wm_compile *c,
printf("undef");
else if( value - c->vreg >= 0 &&
value - c->vreg < BRW_WM_MAX_VREG)
- printf("r%d", value - c->vreg);
+ printf("r%ld", (long) (value - c->vreg));
else if (value - c->creg >= 0 &&
value - c->creg < BRW_WM_MAX_PARAM)
- printf("c%d", value - c->creg);
+ printf("c%ld", (long) (value - c->creg));
else if (value - c->payload.input_interp >= 0 &&
value - c->payload.input_interp < FRAG_ATTRIB_MAX)
- printf("i%d", value - c->payload.input_interp);
+ printf("i%ld", (long) (value - c->payload.input_interp));
else if (value - c->payload.depth >= 0 &&
value - c->payload.depth < FRAG_ATTRIB_MAX)
- printf("d%d", value - c->payload.depth);
+ printf("d%ld", (long) (value - c->payload.depth));
else
printf("?");
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index d9fa2e63354..f3ad01b3fec 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -668,6 +668,28 @@ void emit_cmp(struct brw_compile *p,
}
}
+void emit_sign(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0)
+{
+ GLuint i;
+
+ for (i = 0; i < 4; i++) {
+ if (mask & (1<<i)) {
+ brw_MOV(p, dst[i], brw_imm_f(0.0));
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], brw_imm_f(0));
+ brw_MOV(p, dst[i], brw_imm_f(-1.0));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+ brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, arg0[i], brw_imm_f(0));
+ brw_MOV(p, dst[i], brw_imm_f(1.0));
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ }
+ }
+}
+
void emit_max(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
@@ -709,6 +731,27 @@ void emit_min(struct brw_compile *p,
}
+void emit_dp2(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1)
+{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return; /* Do not emit dead code */
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
+ brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
+
+ brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
+ brw_MAC(p, dst[dst_chan], arg0[1], arg1[1]);
+ brw_set_saturate(p, 0);
+}
+
+
void emit_dp3(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
@@ -809,21 +852,28 @@ void emit_math1(struct brw_wm_compile *c,
const struct brw_reg *arg0)
{
struct brw_compile *p = &c->func;
+ struct intel_context *intel = &p->brw->intel;
int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
GLuint saturate = ((mask & SATURATE) ?
BRW_MATH_SATURATE_SATURATE :
BRW_MATH_SATURATE_NONE);
+ struct brw_reg src;
+
+ if (intel->gen >= 6 && arg0[0].hstride == BRW_HORIZONTAL_STRIDE_0) {
+ /* Gen6 math requires that source and dst horizontal stride be 1.
+ *
+ */
+ src = *dst;
+ brw_MOV(p, src, arg0[0]);
+ } else {
+ src = arg0[0];
+ }
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
assert(is_power_of_two(mask & WRITEMASK_XYZW));
- /* If compressed, this will write message reg 2,3 from arg0.x's 16
- * channels.
- */
- brw_MOV(p, brw_message_reg(2), arg0[0]);
-
/* Send two messages to perform all 16 operations:
*/
brw_push_insn_state(p);
@@ -833,7 +883,7 @@ void emit_math1(struct brw_wm_compile *c,
function,
saturate,
2,
- brw_null_reg(),
+ src,
BRW_MATH_DATA_VECTOR,
BRW_MATH_PRECISION_FULL);
@@ -844,7 +894,7 @@ void emit_math1(struct brw_wm_compile *c,
function,
saturate,
3,
- brw_null_reg(),
+ sechalf(src),
BRW_MATH_DATA_VECTOR,
BRW_MATH_PRECISION_FULL);
}
@@ -873,13 +923,6 @@ void emit_math2(struct brw_wm_compile *c,
brw_push_insn_state(p);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
- brw_MOV(p, brw_message_reg(2), arg0[0]);
- if (c->dispatch_width == 16) {
- brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
- brw_MOV(p, brw_message_reg(4), sechalf(arg0[0]));
- }
-
- brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_MOV(p, brw_message_reg(3), arg1[0]);
if (c->dispatch_width == 16) {
brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
@@ -892,7 +935,7 @@ void emit_math2(struct brw_wm_compile *c,
function,
saturate,
2,
- brw_null_reg(),
+ arg0[0],
BRW_MATH_DATA_VECTOR,
BRW_MATH_PRECISION_FULL);
@@ -905,7 +948,7 @@ void emit_math2(struct brw_wm_compile *c,
function,
saturate,
4,
- brw_null_reg(),
+ sechalf(arg0[0]),
BRW_MATH_DATA_VECTOR,
BRW_MATH_PRECISION_FULL);
}
@@ -1199,6 +1242,7 @@ static void fire_fb_write( struct brw_wm_compile *c,
GLuint eot )
{
struct brw_compile *p = &c->func;
+ struct intel_context *intel = &p->brw->intel;
struct brw_reg dst;
if (c->dispatch_width == 16)
@@ -1209,6 +1253,7 @@ static void fire_fb_write( struct brw_wm_compile *c,
/* Pass through control information:
*/
/* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */
+ if (intel->gen < 6) /* gen6, use headerless for fb write */
{
brw_push_insn_state(p);
brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */
@@ -1222,6 +1267,7 @@ static void fire_fb_write( struct brw_wm_compile *c,
/* Send framebuffer write message: */
/* send (16) null.0<1>:uw m0 r0.0<8;8,1>:uw 0x85a04000:ud { Align1 EOT } */
brw_fb_WRITE(p,
+ c->dispatch_width,
dst,
base_reg,
retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW),
@@ -1263,8 +1309,10 @@ void emit_fb_write(struct brw_wm_compile *c,
{
struct brw_compile *p = &c->func;
struct brw_context *brw = p->brw;
+ struct intel_context *intel = &brw->intel;
GLuint nr = 2;
GLuint channel;
+ int base_reg; /* For gen6 fb write with no header, starting from color payload directly!. */
/* Reserve a space for AA - may not be needed:
*/
@@ -1276,9 +1324,40 @@ void emit_fb_write(struct brw_wm_compile *c,
*/
brw_push_insn_state(p);
+ if (intel->gen >= 6)
+ base_reg = nr;
+ else
+ base_reg = 0;
+
for (channel = 0; channel < 4; channel++) {
- if (c->dispatch_width == 16 && brw->has_compr4) {
- /* By setting the high bit of the MRF register number, we indicate
+ if (intel->gen >= 6) {
+ /* gen6 SIMD16 single source DP write looks like:
+ * m + 0: r0
+ * m + 1: r1
+ * m + 2: g0
+ * m + 3: g1
+ * m + 4: b0
+ * m + 5: b1
+ * m + 6: a0
+ * m + 7: a1
+ */
+ if (c->dispatch_width == 16) {
+ brw_MOV(p, brw_message_reg(nr + channel * 2), arg0[channel]);
+ } else {
+ brw_MOV(p, brw_message_reg(nr + channel), arg0[channel]);
+ }
+ } else if (c->dispatch_width == 16 && brw->has_compr4) {
+ /* pre-gen6 SIMD16 single source DP write looks like:
+ * m + 0: r0
+ * m + 1: g0
+ * m + 2: b0
+ * m + 3: a0
+ * m + 4: r1
+ * m + 5: g1
+ * m + 6: b1
+ * m + 7: a1
+ *
+ * By setting the high bit of the MRF register number, we indicate
* that we want COMPR4 mode - instead of doing the usual destination
* + 1 for the second half we get destination + 4.
*/
@@ -1303,7 +1382,11 @@ void emit_fb_write(struct brw_wm_compile *c,
}
/* skip over the regs populated above:
*/
- nr += 8;
+ if (c->dispatch_width == 16)
+ nr += 8;
+ else
+ nr += 4;
+
brw_pop_insn_state(p);
if (c->key.source_depth_to_render_target)
@@ -1336,11 +1419,16 @@ void emit_fb_write(struct brw_wm_compile *c,
nr += 2;
}
+ if (intel->gen >= 6) {
+ /* Subtract off the message header, since we send headerless. */
+ nr -= 2;
+ }
+
if (!c->key.runtime_check_aads_emit) {
if (c->key.aa_dest_stencil_reg)
emit_aa(c, arg1, 2);
- fire_fb_write(c, 0, nr, target, eot);
+ fire_fb_write(c, base_reg, nr, target, eot);
}
else {
struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD));
@@ -1562,6 +1650,10 @@ void brw_wm_emit( struct brw_wm_compile *c )
emit_ddxy(p, dst, dst_flags, GL_FALSE, args[0]);
break;
+ case OPCODE_DP2:
+ emit_dp2(p, dst, dst_flags, args[0], args[1]);
+ break;
+
case OPCODE_DP3:
emit_dp3(p, dst, dst_flags, args[0], args[1]);
break;
@@ -1673,6 +1765,10 @@ void brw_wm_emit( struct brw_wm_compile *c )
emit_sne(p, dst, dst_flags, args[0], args[1]);
break;
+ case OPCODE_SSG:
+ emit_sign(p, dst, dst_flags, args[0]);
+ break;
+
case OPCODE_LIT:
emit_lit(c, dst, dst_flags, args[0]);
break;
@@ -1724,7 +1820,7 @@ void brw_wm_emit( struct brw_wm_compile *c )
printf("wm-native:\n");
for (i = 0; i < p->nr_insn; i++)
- brw_disasm(stderr, &p->store[i], p->brw->intel.gen);
+ brw_disasm(stdout, &p->store[i], p->brw->intel.gen);
printf("\n");
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 0bef874b887..3870bf10fcb 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -88,6 +88,7 @@ static struct prog_src_register src_reg(GLuint file, GLuint idx)
reg.RelAddr = 0;
reg.Negate = NEGATE_NONE;
reg.Abs = 0;
+ reg.HasIndex2 = 0;
return reg;
}
@@ -1036,13 +1037,12 @@ static void print_insns( const struct prog_instruction *insn,
for (i = 0; i < nr; i++, insn++) {
printf("%3d: ", i);
if (insn->Opcode < MAX_OPCODE)
- _mesa_print_instruction(insn);
+ _mesa_fprint_instruction_opt(stdout, insn, 0, PROG_PRINT_DEBUG, NULL);
else if (insn->Opcode < MAX_WM_OPCODE) {
GLuint idx = insn->Opcode - MAX_OPCODE;
- _mesa_print_alu_instruction(insn,
- wm_opcode_strings[idx],
- 3);
+ _mesa_fprint_alu_instruction(stdout, insn, wm_opcode_strings[idx],
+ 3, PROG_PRINT_DEBUG, NULL);
}
else
printf("965 Opcode %d\n", insn->Opcode);
@@ -1061,7 +1061,8 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
if (INTEL_DEBUG & DEBUG_WM) {
printf("pre-fp:\n");
- _mesa_print_program(&fp->program.Base);
+ _mesa_fprint_program_opt(stdout, &fp->program.Base, PROG_PRINT_DEBUG,
+ GL_TRUE);
printf("\n");
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 575f89b17fa..c1083c59422 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -303,13 +303,13 @@ static void prealloc_reg(struct brw_wm_compile *c)
c->first_free_grf = 0;
for (i = 0; i < 4; i++) {
- if (i < c->key.nr_depth_regs)
+ if (i < (c->key.nr_payload_regs + 1) / 2)
reg = brw_vec8_grf(i * 2, 0);
else
reg = brw_vec8_grf(0, 0);
set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg);
}
- reg_index += 2 * c->key.nr_depth_regs;
+ reg_index += c->key.nr_payload_regs;
/* constants */
{
@@ -380,7 +380,7 @@ static void prealloc_reg(struct brw_wm_compile *c)
}
}
- c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
+ c->prog_data.first_curbe_grf = c->key.nr_payload_regs;
c->prog_data.urb_read_length = urb_read_length;
c->prog_data.curb_read_length = c->nr_creg;
c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, reg_index, 0);
@@ -1803,12 +1803,15 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
#define MAX_IF_DEPTH 32
#define MAX_LOOP_DEPTH 32
struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH];
+ int if_depth_in_loop[MAX_LOOP_DEPTH];
GLuint i, if_depth = 0, loop_depth = 0;
struct brw_compile *p = &c->func;
struct brw_indirect stack_index = brw_indirect(0, 0);
c->out_of_regs = GL_FALSE;
+ if_depth_in_loop[loop_depth] = 0;
+
prealloc_reg(c);
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
@@ -1903,6 +1906,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
case OPCODE_SWZ:
emit_alu1(p, brw_MOV, dst, dst_flags, args[0]);
break;
+ case OPCODE_DP2:
+ emit_dp2(p, dst, dst_flags, args[0], args[1]);
+ break;
case OPCODE_DP3:
emit_dp3(p, dst, dst_flags, args[0], args[1]);
break;
@@ -1971,6 +1977,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
emit_sop(p, dst, dst_flags,
BRW_CONDITIONAL_NEQ, args[0], args[1]);
break;
+ case OPCODE_SSG:
+ emit_sign(p, dst, dst_flags, args[0]);
+ break;
case OPCODE_MUL:
emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]);
break;
@@ -2014,6 +2023,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
case OPCODE_IF:
assert(if_depth < MAX_IF_DEPTH);
if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);
+ if_depth_in_loop[loop_depth]++;
break;
case OPCODE_ELSE:
assert(if_depth > 0);
@@ -2022,6 +2032,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
case OPCODE_ENDIF:
assert(if_depth > 0);
brw_ENDIF(p, if_inst[--if_depth]);
+ if_depth_in_loop[loop_depth]--;
break;
case OPCODE_BGNSUB:
brw_save_label(p, inst->Comment, p->nr_insn);
@@ -2056,13 +2067,14 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
case OPCODE_BGNLOOP:
/* XXX may need to invalidate the current_constant regs */
loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
+ if_depth_in_loop[loop_depth] = 0;
break;
case OPCODE_BRK:
- brw_BREAK(p);
+ brw_BREAK(p, if_depth_in_loop[loop_depth]);
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
case OPCODE_CONT:
- brw_CONT(p);
+ brw_CONT(p, if_depth_in_loop[loop_depth]);
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
case OPCODE_ENDLOOP:
@@ -2082,12 +2094,10 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
if (inst0->header.opcode == BRW_OPCODE_BREAK &&
inst0->bits3.if_else.jump_count == 0) {
inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
- inst0->bits3.if_else.pop_count = 0;
}
else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
inst0->bits3.if_else.jump_count == 0) {
inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
- inst0->bits3.if_else.pop_count = 0;
}
}
}
@@ -2111,7 +2121,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
if (INTEL_DEBUG & DEBUG_WM) {
printf("wm-native:\n");
for (i = 0; i < p->nr_insn; i++)
- brw_disasm(stderr, &p->store[i], intel->gen);
+ brw_disasm(stdout, &p->store[i], intel->gen);
printf("\n");
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_iz.c b/src/mesa/drivers/dri/i965/brw_wm_iz.c
index 5e399ac62a8..8505ef19510 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_iz.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_iz.c
@@ -152,6 +152,6 @@ void brw_wm_lookup_iz( GLuint line_aa,
reg+=2;
}
- key->nr_depth_regs = (reg+1)/2;
+ key->nr_payload_regs = reg;
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
index 05de85a957e..8fc960b4456 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
@@ -379,7 +379,7 @@ static void pass0_init_payload( struct brw_wm_compile *c )
GLuint i;
for (i = 0; i < 4; i++) {
- GLuint j = i >= c->key.nr_depth_regs ? 0 : i;
+ GLuint j = i >= (c->key.nr_payload_regs + 1) / 2 ? 0 : i;
pass0_set_fpreg_value( c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i,
&c->payload.depth[j] );
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
index b4493940292..962515a99e9 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
@@ -158,6 +158,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )
case OPCODE_FLR:
case OPCODE_FRC:
case OPCODE_MOV:
+ case OPCODE_SSG:
case OPCODE_SWZ:
case OPCODE_TRUNC:
read0 = writemask;
@@ -254,6 +255,11 @@ void brw_wm_pass1( struct brw_wm_compile *c )
read2 = WRITEMASK_W; /* pixel w */
break;
+ case OPCODE_DP2:
+ read0 = WRITEMASK_XY;
+ read1 = WRITEMASK_XY;
+ break;
+
case OPCODE_DP3:
read0 = WRITEMASK_XYZ;
read1 = WRITEMASK_XYZ;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
index 31303febf09..54acb3038b5 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c
@@ -76,7 +76,7 @@ static void init_registers( struct brw_wm_compile *c )
for (j = 0; j < c->grf_limit; j++)
c->pass2_grf[j].nextuse = BRW_WM_MAX_INSN;
- for (j = 0; j < c->key.nr_depth_regs; j++)
+ for (j = 0; j < (c->key.nr_payload_regs + 1) / 2; j++)
prealloc_reg(c, &c->payload.depth[j], i++);
for (j = 0; j < c->nr_creg; j++)
@@ -101,7 +101,7 @@ static void init_registers( struct brw_wm_compile *c )
assert(nr_interp_regs >= 1);
- c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
+ c->prog_data.first_curbe_grf = ALIGN(c->key.nr_payload_regs, 2);
c->prog_data.urb_read_length = nr_interp_regs * 2;
c->prog_data.curb_read_length = c->nr_creg * 2;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index c1cf4db1cae..6699d0a73e6 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -104,8 +104,22 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
key->uses_kill = fp->UsesKill || ctx->Color.AlphaEnabled;
key->is_glsl = bfp->isGLSL;
- /* temporary sanity check assertion */
- ASSERT(bfp->isGLSL == brw_wm_is_glsl(fp));
+ /* If using the fragment shader backend, the program is always
+ * 8-wide.
+ */
+ if (ctx->Shader.CurrentProgram) {
+ int i;
+
+ for (i = 0; i < ctx->Shader.CurrentProgram->_NumLinkedShaders; i++) {
+ struct brw_shader *shader =
+ (struct brw_shader *)ctx->Shader.CurrentProgram->_LinkedShaders[i];;
+
+ if (shader->base.Type == GL_FRAGMENT_SHADER &&
+ shader->ir != NULL) {
+ key->is_glsl = GL_TRUE;
+ }
+ }
+ }
/* _NEW_DEPTH */
key->stats_wm = intel->stats_wm;
diff --git a/src/mesa/drivers/dri/i965/gen6_cc.c b/src/mesa/drivers/dri/i965/gen6_cc.c
index f7acad69129..26f1070a164 100644
--- a/src/mesa/drivers/dri/i965/gen6_cc.c
+++ b/src/mesa/drivers/dri/i965/gen6_cc.c
@@ -267,9 +267,9 @@ static void upload_cc_state_pointers(struct brw_context *brw)
BEGIN_BATCH(4);
OUT_BATCH(CMD_3D_CC_STATE_POINTERS << 16 | (4 - 2));
- OUT_RELOC(brw->cc.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
OUT_RELOC(brw->cc.blend_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
OUT_RELOC(brw->cc.depth_stencil_state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
+ OUT_RELOC(brw->cc.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 1);
ADVANCE_BATCH();
intel_batchbuffer_emit_mi_flush(intel->batch);
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 863c85449d9..2cd640de175 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -34,18 +34,59 @@
#include "intel_batchbuffer.h"
static void
+prepare_wm_constants(struct brw_context *brw)
+{
+ struct intel_context *intel = &brw->intel;
+ GLcontext *ctx = &intel->ctx;
+ const struct brw_fragment_program *fp =
+ brw_fragment_program_const(brw->fragment_program);
+
+ drm_intel_bo_unreference(brw->wm.push_const_bo);
+ brw->wm.push_const_bo = NULL;
+
+ /* Updates the ParamaterValues[i] pointers for all parameters of the
+ * basic type of PROGRAM_STATE_VAR.
+ */
+ /* XXX: Should this happen somewhere before to get our state flag set? */
+ _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
+
+ if (brw->wm.prog_data->nr_params != 0) {
+ float *constants;
+ unsigned int i;
+
+ brw->wm.push_const_bo = drm_intel_bo_alloc(intel->bufmgr,
+ "WM constant_bo",
+ brw->wm.prog_data->nr_params *
+ sizeof(float),
+ 4096);
+ drm_intel_gem_bo_map_gtt(brw->wm.push_const_bo);
+ constants = brw->wm.push_const_bo->virtual;
+ for (i = 0; i < brw->wm.prog_data->nr_params; i++) {
+ constants[i] = *brw->wm.prog_data->param[i];
+ }
+ drm_intel_gem_bo_unmap_gtt(brw->wm.push_const_bo);
+ }
+}
+
+const struct brw_tracked_state gen6_wm_constants = {
+ .dirty = {
+ .mesa = _NEW_PROGRAM_CONSTANTS,
+ .brw = 0,
+ .cache = 0,
+ },
+ .prepare = prepare_wm_constants,
+};
+
+static void
upload_wm_state(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
GLcontext *ctx = &intel->ctx;
const struct brw_fragment_program *fp =
brw_fragment_program_const(brw->fragment_program);
- unsigned int nr_params = fp->program.Base.Parameters->NumParameters;
- drm_intel_bo *constant_bo;
- int i;
uint32_t dw2, dw4, dw5, dw6;
- if (fp->use_const_buffer || nr_params == 0) {
+ if (fp->use_const_buffer || brw->wm.prog_data->nr_params == 0) {
/* Disable the push constant buffers. */
BEGIN_BATCH(5);
OUT_BATCH(CMD_3D_CONSTANT_PS_STATE << 16 | (5 - 2));
@@ -55,35 +96,17 @@ upload_wm_state(struct brw_context *brw)
OUT_BATCH(0);
ADVANCE_BATCH();
} else {
- /* Updates the ParamaterValues[i] pointers for all parameters of the
- * basic type of PROGRAM_STATE_VAR.
- */
- _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
-
- constant_bo = drm_intel_bo_alloc(intel->bufmgr, "WM constant_bo",
- nr_params * 4 * sizeof(float),
- 4096);
- drm_intel_gem_bo_map_gtt(constant_bo);
- for (i = 0; i < nr_params; i++) {
- memcpy((char *)constant_bo->virtual + i * 4 * sizeof(float),
- fp->program.Base.Parameters->ParameterValues[i],
- 4 * sizeof(float));
- }
- drm_intel_gem_bo_unmap_gtt(constant_bo);
-
BEGIN_BATCH(5);
OUT_BATCH(CMD_3D_CONSTANT_PS_STATE << 16 |
GEN6_CONSTANT_BUFFER_0_ENABLE |
(5 - 2));
- OUT_RELOC(constant_bo,
+ OUT_RELOC(brw->wm.push_const_bo,
I915_GEM_DOMAIN_RENDER, 0, /* XXX: bad domain */
- ALIGN(nr_params, 2) / 2 - 1);
+ ALIGN(brw->wm.prog_data->nr_params, 8) / 8 - 1);
OUT_BATCH(0);
OUT_BATCH(0);
OUT_BATCH(0);
ADVANCE_BATCH();
-
- drm_intel_bo_unreference(constant_bo);
}
intel_batchbuffer_emit_mi_flush(intel->batch);
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index 8ab41f8d279..117d4daf3ba 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -202,6 +202,9 @@ intel_bufferobj_subdata(GLcontext * ctx,
struct intel_context *intel = intel_context(ctx);
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+ if (size == 0)
+ return;
+
assert(intel_obj);
if (intel_obj->region)
@@ -426,6 +429,9 @@ intel_bufferobj_flush_mapped_range(GLcontext *ctx, GLenum target,
if (intel_obj->range_map_buffer == NULL)
return;
+ if (length == 0)
+ return;
+
temp_bo = drm_intel_bo_alloc(intel->bufmgr, "range map flush", length, 64);
drm_intel_bo_subdata(temp_bo, 0, length, intel_obj->range_map_buffer);
diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h
index 72a74322ee5..b5f180bbc88 100644
--- a/src/mesa/drivers/dri/intel/intel_chipset.h
+++ b/src/mesa/drivers/dri/intel/intel_chipset.h
@@ -73,6 +73,7 @@
#define PCI_CHIP_SANDYBRIDGE 0x0102
#define PCI_CHIP_SANDYBRIDGE_M 0x0106
+#define PCI_CHIP_SANDYBRIDGE_M_D0 0x0126
#define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \
devid == PCI_CHIP_I915_GM || \
@@ -119,7 +120,8 @@
#define IS_IRONLAKE(devid) IS_GEN5(devid)
#define IS_GEN6(devid) (devid == PCI_CHIP_SANDYBRIDGE || \
- devid == PCI_CHIP_SANDYBRIDGE_M)
+ devid == PCI_CHIP_SANDYBRIDGE_M || \
+ devid == PCI_CHIP_SANDYBRIDGE_M_D0)
#define IS_965(devid) (IS_GEN4(devid) || \
IS_G4X(devid) || \
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index e19f44035fd..a9ba93d24bb 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -377,7 +377,8 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
intel_region_reference(&region, depth_region);
}
else
- region = intel_region_alloc_for_handle(intel, buffers[i].cpp,
+ region = intel_region_alloc_for_handle(intel->intelScreen,
+ buffers[i].cpp,
drawable->w,
drawable->h,
buffers[i].pitch / buffers[i].cpp,
@@ -720,6 +721,8 @@ intelInitContext(struct intel_context *intel,
ctx->Const.MaxPointSizeAA = 3.0;
ctx->Const.PointSizeGranularity = 1.0;
+ ctx->Const.MaxSamples = 1.0;
+
/* reinitialize the context point state.
* It depend on constants in __GLcontextRec::Const
*/
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index c7ac2de01e6..28d53284fdf 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -32,14 +32,26 @@
#include "main/mtypes.h"
#include "main/mm.h"
-#include "texmem.h"
#include "dri_metaops.h"
+
+#ifdef __cplusplus
+extern "C" {
+ /* Evil hack for using libdrm in a c++ compiler. */
+ #define virtual virt
+#endif
+
#include "drm.h"
#include "intel_bufmgr.h"
#include "intel_screen.h"
#include "intel_tex_obj.h"
#include "i915_drm.h"
+
+#ifdef __cplusplus
+ #undef virtual
+}
+#endif
+
#include "tnl/t_vertex.h"
#define TAG(x) intel##x
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index edba1fc2f2b..bf22a423fcb 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -50,8 +50,9 @@
#define need_GL_EXT_cull_vertex
#define need_GL_EXT_draw_buffers2
#define need_GL_EXT_fog_coord
-#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_framebuffer_blit
+#define need_GL_EXT_framebuffer_multisample
+#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_gpu_program_parameters
#define need_GL_EXT_point_parameters
#define need_GL_EXT_provoking_vertex
@@ -111,6 +112,7 @@ static const struct dri_extension card_extensions[] = {
{ "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions },
{ "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions },
{ "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
+ { "GL_EXT_framebuffer_multisample", GL_EXT_framebuffer_multisample_functions },
{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{ "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
{ "GL_EXT_packed_depth_stencil", NULL },
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 4a83886fc16..2693b5fa72e 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -137,27 +137,21 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
rb->Format = MESA_FORMAT_A8;
rb->DataType = GL_UNSIGNED_BYTE;
break;
+ case GL_DEPTH_COMPONENT16:
+ rb->Format = MESA_FORMAT_Z16;
+ rb->DataType = GL_UNSIGNED_SHORT;
+ break;
case GL_STENCIL_INDEX:
case GL_STENCIL_INDEX1_EXT:
case GL_STENCIL_INDEX4_EXT:
case GL_STENCIL_INDEX8_EXT:
case GL_STENCIL_INDEX16_EXT:
- /* alloc a depth+stencil buffer */
- rb->Format = MESA_FORMAT_S8_Z24;
- rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
- break;
- case GL_DEPTH_COMPONENT16:
- rb->Format = MESA_FORMAT_Z16;
- rb->DataType = GL_UNSIGNED_SHORT;
- break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
- rb->Format = MESA_FORMAT_S8_Z24;
- rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
- break;
case GL_DEPTH_STENCIL_EXT:
case GL_DEPTH24_STENCIL8_EXT:
+ /* alloc a depth+stencil buffer */
rb->Format = MESA_FORMAT_S8_Z24;
rb->DataType = GL_UNSIGNED_INT_24_8_EXT;
break;
@@ -182,7 +176,7 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
/* alloc hardware renderbuffer */
DBG("Allocating %d x %d Intel RBO\n", width, height);
- irb->region = intel_region_alloc(intel, I915_TILING_NONE, cpp,
+ irb->region = intel_region_alloc(intel->intelScreen, I915_TILING_NONE, cpp,
width, height, GL_TRUE);
if (!irb->region)
return GL_FALSE; /* out of memory? */
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 39ac0205fa1..d316d34d690 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -30,6 +30,7 @@
#include "intel_regions.h"
#include "intel_tex_layout.h"
#include "main/enums.h"
+#include "main/formats.h"
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
@@ -136,7 +137,7 @@ intel_miptree_create(struct intel_context *intel,
return NULL;
}
- mt->region = intel_region_alloc(intel,
+ mt->region = intel_region_alloc(intel->intelScreen,
tiling,
mt->cpp,
mt->total_width,
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 680d18ba299..e87e29462c3 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -142,10 +142,10 @@ intel_region_unmap(struct intel_context *intel, struct intel_region *region)
}
static struct intel_region *
-intel_region_alloc_internal(struct intel_context *intel,
+intel_region_alloc_internal(struct intel_screen *screen,
GLuint cpp,
GLuint width, GLuint height, GLuint pitch,
- drm_intel_bo *buffer)
+ uint32_t tiling, drm_intel_bo *buffer)
{
struct intel_region *region;
@@ -164,44 +164,52 @@ intel_region_alloc_internal(struct intel_context *intel,
region->pitch = pitch;
region->refcount = 1;
region->buffer = buffer;
-
- /* Default to no tiling */
- region->tiling = I915_TILING_NONE;
+ region->tiling = tiling;
+ region->screen = screen;
_DBG("%s <-- %p\n", __FUNCTION__, region);
return region;
}
struct intel_region *
-intel_region_alloc(struct intel_context *intel,
+intel_region_alloc(struct intel_screen *screen,
uint32_t tiling,
GLuint cpp, GLuint width, GLuint height,
GLboolean expect_accelerated_upload)
{
drm_intel_bo *buffer;
- struct intel_region *region;
unsigned long flags = 0;
unsigned long aligned_pitch;
if (expect_accelerated_upload)
flags |= BO_ALLOC_FOR_RENDER;
- buffer = drm_intel_bo_alloc_tiled(intel->bufmgr, "region",
+ buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "region",
width, height, cpp,
&tiling, &aligned_pitch, flags);
- region = intel_region_alloc_internal(intel, cpp, width, height,
- aligned_pitch / cpp, buffer);
- if (region == NULL)
- return region;
+ return intel_region_alloc_internal(screen, cpp, width, height,
+ aligned_pitch / cpp, tiling, buffer);
+}
- region->tiling = tiling;
+GLboolean
+intel_region_flink(struct intel_region *region, uint32_t *name)
+{
+ if (region->name == 0) {
+ if (drm_intel_bo_flink(region->buffer, &region->name))
+ return GL_FALSE;
+
+ _mesa_HashInsert(region->screen->named_regions,
+ region->name, region);
+ }
- return region;
+ *name = region->name;
+
+ return GL_TRUE;
}
struct intel_region *
-intel_region_alloc_for_handle(struct intel_context *intel,
+intel_region_alloc_for_handle(struct intel_screen *screen,
GLuint cpp,
GLuint width, GLuint height, GLuint pitch,
GLuint handle, const char *name)
@@ -209,9 +217,9 @@ intel_region_alloc_for_handle(struct intel_context *intel,
struct intel_region *region, *dummy;
drm_intel_bo *buffer;
int ret;
- uint32_t bit_6_swizzle;
+ uint32_t bit_6_swizzle, tiling;
- region = _mesa_HashLookup(intel->intelScreen->named_regions, handle);
+ region = _mesa_HashLookup(screen->named_regions, handle);
if (region != NULL) {
dummy = NULL;
if (region->width != width || region->height != height ||
@@ -225,25 +233,26 @@ intel_region_alloc_for_handle(struct intel_context *intel,
return dummy;
}
- buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, handle);
-
- region = intel_region_alloc_internal(intel, cpp,
- width, height, pitch, buffer);
- if (region == NULL)
- return region;
-
- ret = drm_intel_bo_get_tiling(region->buffer, &region->tiling,
- &bit_6_swizzle);
+ buffer = intel_bo_gem_create_from_name(screen->bufmgr, name, handle);
+ if (buffer == NULL)
+ return NULL;
+ ret = drm_intel_bo_get_tiling(buffer, &tiling, &bit_6_swizzle);
if (ret != 0) {
fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n",
handle, name, strerror(-ret));
- intel_region_release(&region);
+ drm_intel_bo_unreference(buffer);
+ return NULL;
+ }
+
+ region = intel_region_alloc_internal(screen, cpp,
+ width, height, pitch, tiling, buffer);
+ if (region == NULL) {
+ drm_intel_bo_unreference(buffer);
return NULL;
}
region->name = handle;
- region->screen = intel->intelScreen;
- _mesa_HashInsert(intel->intelScreen->named_regions, handle, region);
+ _mesa_HashInsert(screen->named_regions, handle, region);
return region;
}
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index 6bbed32f2a2..8464a5e937d 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -76,18 +76,21 @@ struct intel_region
/* Allocate a refcounted region. Pointers to regions should only be
* copied by calling intel_reference_region().
*/
-struct intel_region *intel_region_alloc(struct intel_context *intel,
+struct intel_region *intel_region_alloc(struct intel_screen *screen,
uint32_t tiling,
GLuint cpp, GLuint width,
GLuint height,
GLboolean expect_accelerated_upload);
struct intel_region *
-intel_region_alloc_for_handle(struct intel_context *intel,
+intel_region_alloc_for_handle(struct intel_screen *screen,
GLuint cpp,
GLuint width, GLuint height, GLuint pitch,
unsigned int handle, const char *name);
+GLboolean
+intel_region_flink(struct intel_region *region, uint32_t *name);
+
void intel_region_reference(struct intel_region **dst,
struct intel_region *src);
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 15a465c6402..0a542a7303d 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -70,7 +70,7 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
DRI_CONF_OPT_END
- DRI_CONF_OPT_BEGIN(fragment_shader, bool, false)
+ DRI_CONF_OPT_BEGIN(fragment_shader, bool, true)
DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.")
DRI_CONF_OPT_END
@@ -159,7 +159,8 @@ intel_create_image_from_name(__DRIcontext *context,
image->data = loaderPrivate;
cpp = _mesa_get_format_bytes(image->format);
- image->region = intel_region_alloc_for_handle(intel, cpp, width, height,
+ image->region = intel_region_alloc_for_handle(intel->intelScreen,
+ cpp, width, height,
pitch, name, "image");
if (image->region == NULL) {
FREE(image);
@@ -206,11 +207,79 @@ intel_destroy_image(__DRIimage *image)
FREE(image);
}
+static __DRIimage *
+intel_create_image(__DRIscreen *screen,
+ int width, int height, int format,
+ unsigned int use,
+ void *loaderPrivate)
+{
+ __DRIimage *image;
+ struct intel_screen *intelScreen = screen->private;
+ int cpp;
+
+ image = CALLOC(sizeof *image);
+ if (image == NULL)
+ return NULL;
+
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_RGB565:
+ image->format = MESA_FORMAT_RGB565;
+ image->internal_format = GL_RGB;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ case __DRI_IMAGE_FORMAT_XRGB8888:
+ image->format = MESA_FORMAT_XRGB8888;
+ image->internal_format = GL_RGB;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ case __DRI_IMAGE_FORMAT_ARGB8888:
+ image->format = MESA_FORMAT_ARGB8888;
+ image->internal_format = GL_RGBA;
+ image->data_type = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ free(image);
+ return NULL;
+ }
+
+ image->data = loaderPrivate;
+ cpp = _mesa_get_format_bytes(image->format);
+
+ image->region =
+ intel_region_alloc(intelScreen, I915_TILING_NONE,
+ cpp, width, height, GL_TRUE);
+ if (image->region == NULL) {
+ FREE(image);
+ return NULL;
+ }
+
+ return image;
+}
+
+static GLboolean
+intel_query_image(__DRIimage *image, int attrib, int *value)
+{
+ switch (attrib) {
+ case __DRI_IMAGE_ATTRIB_STRIDE:
+ *value = image->region->pitch * image->region->cpp;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_HANDLE:
+ *value = image->region->buffer->handle;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_NAME:
+ return intel_region_flink(image->region, (uint32_t *) value);
+ default:
+ return GL_FALSE;
+ }
+}
+
static struct __DRIimageExtensionRec intelImageExtension = {
{ __DRI_IMAGE, __DRI_IMAGE_VERSION },
intel_create_image_from_name,
intel_create_image_from_renderbuffer,
intel_destroy_image,
+ intel_create_image,
+ intel_query_image
};
static const __DRIextension *intelScreenExtensions[] = {
diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h
index 4bb012dc65e..cd77dd5b8e4 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.h
+++ b/src/mesa/drivers/dri/intel/intel_tex.h
@@ -31,8 +31,6 @@
#include "main/mtypes.h"
#include "main/formats.h"
#include "intel_context.h"
-#include "texmem.h"
-
void intelInitTextureFuncs(struct dd_function_table *functions);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
index 4ec864c181c..6452fe218e5 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c
@@ -138,5 +138,7 @@ nouveau_driver_functions_init(struct dd_function_table *functions)
functions->DrawPixels = _mesa_meta_DrawPixels;
functions->CopyPixels = _mesa_meta_CopyPixels;
functions->Bitmap = _mesa_meta_Bitmap;
+#if FEATURE_EXT_framebuffer_blit
functions->BlitFramebuffer = _mesa_meta_BlitFramebuffer;
+#endif
}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
index bd1273beea7..32d8f2d0f9b 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c
@@ -262,10 +262,12 @@ nouveau_finish_render_texture(GLcontext *ctx,
void
nouveau_fbo_functions_init(struct dd_function_table *functions)
{
+#if FEATURE_EXT_framebuffer_object
functions->NewFramebuffer = nouveau_framebuffer_new;
functions->NewRenderbuffer = nouveau_renderbuffer_new;
functions->BindFramebuffer = nouveau_bind_framebuffer;
functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer;
functions->RenderTexture = nouveau_render_texture;
functions->FinishRenderTexture = nouveau_finish_render_texture;
+#endif
}
diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile
index 3167d49bcae..d0eb1707845 100644
--- a/src/mesa/drivers/dri/r300/compiler/Makefile
+++ b/src/mesa/drivers/dri/r300/compiler/Makefile
@@ -23,6 +23,7 @@ C_SOURCES = \
radeon_dataflow_deadcode.c \
radeon_dataflow_swizzles.c \
radeon_optimize.c \
+ radeon_remove_constants.c \
radeon_rename_regs.c \
r3xx_fragprog.c \
r300_fragprog.c \
diff --git a/src/mesa/drivers/dri/r300/compiler/SConscript b/src/mesa/drivers/dri/r300/compiler/SConscript
index c6f47a6f8a4..847857b1425 100755
--- a/src/mesa/drivers/dri/r300/compiler/SConscript
+++ b/src/mesa/drivers/dri/r300/compiler/SConscript
@@ -22,6 +22,7 @@ r300compiler = env.ConvenienceLibrary(
'radeon_pair_schedule.c',
'radeon_pair_regalloc.c',
'radeon_optimize.c',
+ 'radeon_remove_constants.c',
'radeon_rename_regs.c',
'radeon_emulate_branches.c',
'radeon_emulate_loops.c',
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
index d2fa816894c..8613ec51091 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
@@ -30,6 +30,7 @@
#include "radeon_program_alu.h"
#include "radeon_program_tex.h"
#include "radeon_rename_regs.h"
+#include "radeon_remove_constants.h"
#include "r300_fragprog.h"
#include "r300_fragprog_swizzle.h"
#include "r500_fragprog.h"
@@ -180,6 +181,13 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
debug_program_log(c, "after dataflow passes");
+ if (c->Base.remove_unused_constants) {
+ rc_remove_unused_constants(&c->Base,
+ &c->code->constants_remap_table);
+
+ debug_program_log(c, "after constants cleanup");
+ }
+
if(!c->Base.is_r500) {
/* This pass makes it easier for the scheduler to group TEX
* instructions and reduces the chances of creating too
@@ -224,4 +232,14 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
r300FragmentProgramDump(c->code);
}
}
+
+ /* Check the number of constants. */
+ if (!c->Base.Error) {
+ unsigned max = c->Base.is_r500 ? R500_PFS_NUM_CONST_REGS : R300_PFS_NUM_CONST_REGS;
+
+ if (c->Base.Program.Constants.Count > max) {
+ rc_error(&c->Base, "Too many constants. Max: %i, Got: %i\n",
+ max, c->Base.Program.Constants.Count);
+ }
+ }
}
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 666c9c2a7a9..b05b3aabf30 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -31,6 +31,7 @@
#include "radeon_swizzle.h"
#include "radeon_emulate_branches.h"
#include "radeon_emulate_loops.h"
+#include "radeon_remove_constants.h"
struct loop {
int BgnLoop;
@@ -465,7 +466,7 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
{
struct rc_instruction *rci;
- struct loop * loops;
+ struct loop * loops = NULL;
int current_loop_depth = 0;
int loops_reserved = 0;
@@ -484,6 +485,21 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
if (!valid_dst(compiler->code, &vpi->DstReg))
continue;
+ if (rc_get_opcode_info(vpi->Opcode)->HasDstReg) {
+ /* Relative addressing of destination operands is not supported yet. */
+ if (vpi->DstReg.RelAddr) {
+ rc_error(&compiler->Base, "Vertex program does not support relative "
+ "addressing of destination operands (yet).\n");
+ return;
+ }
+
+ /* Neither is Saturate. */
+ if (vpi->SaturateMode != RC_SATURATE_NONE) {
+ rc_error(&compiler->Base, "Vertex program does not support the Saturate "
+ "modifier (yet).\n");
+ }
+ }
+
if (compiler->code->length >= R500_VS_MAX_ALU_DWORDS ||
(compiler->code->length >= R300_VS_MAX_ALU_DWORDS && !compiler->Base.is_r500)) {
rc_error(&compiler->Base, "Vertex program has too many instructions\n");
@@ -543,10 +559,16 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
}
case RC_OPCODE_ENDLOOP:
{
- struct loop * l = &loops[current_loop_depth - 1];
- unsigned int act_addr = l->BgnLoop - 1;
- unsigned int last_addr = (compiler->code->length / 4) - 1;
- unsigned int ret_addr = l->BgnLoop;
+ struct loop * l;
+ unsigned int act_addr;
+ unsigned int last_addr;
+ unsigned int ret_addr;
+
+ assert(loops);
+ l = &loops[current_loop_depth - 1];
+ act_addr = l->BgnLoop - 1;
+ last_addr = (compiler->code->length / 4) - 1;
+ ret_addr = l->BgnLoop;
if (loops_reserved >= R300_VS_MAX_FC_OPS) {
rc_error(&compiler->Base,
@@ -624,10 +646,9 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
struct temporary_allocation * ta;
unsigned int i, j;
- compiler->code->num_temporaries = 0;
memset(hwtemps, 0, sizeof(hwtemps));
- /* Pass 1: Count original temporaries and allocate structures */
+ /* Pass 1: Count original temporaries. */
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
@@ -645,12 +666,30 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
}
}
}
+ compiler->code->num_temporaries = num_orig_temps;
+
+ /* Pass 2: If there is relative addressing of temporaries, we cannot change register indices. Give up. */
+ for (inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
+ const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+ if (opcode->HasDstReg)
+ if (inst->U.I.DstReg.RelAddr)
+ return;
+ for (i = 0; i < opcode->NumSrcRegs; ++i) {
+ if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY &&
+ inst->U.I.SrcReg[i].RelAddr) {
+ return;
+ }
+ }
+ }
+
+ compiler->code->num_temporaries = 0;
ta = (struct temporary_allocation*)memory_pool_malloc(&compiler->Base.Pool,
sizeof(struct temporary_allocation) * num_orig_temps);
memset(ta, 0, sizeof(struct temporary_allocation) * num_orig_temps);
- /* Pass 2: Determine original temporary lifetimes */
+ /* Pass 3: Determine original temporary lifetimes */
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
/* Instructions inside of loops need to use the ENDLOOP
@@ -685,7 +724,7 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
}
}
- /* Pass 3: Register allocation */
+ /* Pass 4: Register allocation */
for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
@@ -853,6 +892,76 @@ static int swizzle_is_native(rc_opcode opcode, struct rc_src_register reg)
return 1;
}
+static void transform_negative_addressing(struct r300_vertex_program_compiler *c,
+ struct rc_instruction *arl,
+ struct rc_instruction *end,
+ int min_offset)
+{
+ struct rc_instruction *inst, *add;
+ unsigned const_swizzle;
+
+ /* Transform ARL */
+ add = rc_insert_new_instruction(&c->Base, arl->Prev);
+ add->U.I.Opcode = RC_OPCODE_ADD;
+ add->U.I.DstReg.File = RC_FILE_TEMPORARY;
+ add->U.I.DstReg.Index = rc_find_free_temporary(&c->Base);
+ add->U.I.DstReg.WriteMask = RC_MASK_X;
+ add->U.I.SrcReg[0] = arl->U.I.SrcReg[0];
+ add->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
+ add->U.I.SrcReg[1].Index = rc_constants_add_immediate_scalar(&c->Base.Program.Constants,
+ min_offset, &const_swizzle);
+ add->U.I.SrcReg[1].Swizzle = const_swizzle;
+
+ arl->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+ arl->U.I.SrcReg[0].Index = add->U.I.DstReg.Index;
+ arl->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XXXX;
+
+ /* Rewrite offsets up to and excluding inst. */
+ for (inst = arl->Next; inst != end; inst = inst->Next) {
+ const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+ for (unsigned i = 0; i < opcode->NumSrcRegs; i++)
+ if (inst->U.I.SrcReg[i].RelAddr)
+ inst->U.I.SrcReg[i].Index -= min_offset;
+ }
+}
+
+static void rc_emulate_negative_addressing(struct r300_vertex_program_compiler *c)
+{
+ struct rc_instruction *inst, *lastARL = NULL;
+ int min_offset = 0;
+
+ for (inst = c->Base.Program.Instructions.Next; inst != &c->Base.Program.Instructions; inst = inst->Next) {
+ const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+ if (inst->U.I.Opcode == RC_OPCODE_ARL) {
+ if (lastARL != NULL && min_offset < 0)
+ transform_negative_addressing(c, lastARL, inst, min_offset);
+
+ lastARL = inst;
+ min_offset = 0;
+ continue;
+ }
+
+ for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
+ if (inst->U.I.SrcReg[i].RelAddr &&
+ inst->U.I.SrcReg[i].Index < 0) {
+ /* ARL must precede any indirect addressing. */
+ if (lastARL == NULL) {
+ rc_error(&c->Base, "Vertex shader: Found relative addressing without ARL.");
+ return;
+ }
+
+ if (inst->U.I.SrcReg[i].Index < min_offset)
+ min_offset = inst->U.I.SrcReg[i].Index;
+ }
+ }
+ }
+
+ if (lastARL != NULL && min_offset < 0)
+ transform_negative_addressing(c, lastARL, inst, min_offset);
+}
+
static void debug_program_log(struct r300_vertex_program_compiler* c, const char * where)
{
if (c->Base.Debug) {
@@ -868,44 +977,56 @@ static struct rc_swizzle_caps r300_vertprog_swizzle_caps = {
};
-void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
+void r3xx_compile_vertex_program(struct r300_vertex_program_compiler *c)
{
struct emulate_loop_state loop_state;
- compiler->Base.SwizzleCaps = &r300_vertprog_swizzle_caps;
+ c->Base.SwizzleCaps = &r300_vertprog_swizzle_caps;
- addArtificialOutputs(compiler);
+ addArtificialOutputs(c);
- debug_program_log(compiler, "before compilation");
+ debug_program_log(c, "before compilation");
- if (compiler->Base.is_r500)
- rc_transform_loops(&compiler->Base, &loop_state, R500_VS_MAX_ALU);
+ if (c->Base.is_r500)
+ rc_transform_loops(&c->Base, &loop_state, R500_VS_MAX_ALU);
else
- rc_transform_loops(&compiler->Base, &loop_state, R300_VS_MAX_ALU);
+ rc_transform_loops(&c->Base, &loop_state, R300_VS_MAX_ALU);
+ if (c->Base.Error)
+ return;
- debug_program_log(compiler, "after emulate loops");
+ debug_program_log(c, "after emulate loops");
- if (!compiler->Base.is_r500) {
- rc_emulate_branches(&compiler->Base);
- debug_program_log(compiler, "after emulate branches");
+ if (!c->Base.is_r500) {
+ rc_emulate_branches(&c->Base);
+ if (c->Base.Error)
+ return;
+ debug_program_log(c, "after emulate branches");
}
- if (compiler->Base.is_r500) {
+ rc_emulate_negative_addressing(c);
+
+ debug_program_log(c, "after negative addressing emulation");
+
+ if (c->Base.is_r500) {
struct radeon_program_transformation transformations[] = {
{ &r300_transform_vertex_alu, 0 },
{ &r300_transform_trig_scale_vertex, 0 }
};
- radeonLocalTransform(&compiler->Base, 2, transformations);
+ radeonLocalTransform(&c->Base, 2, transformations);
+ if (c->Base.Error)
+ return;
- debug_program_log(compiler, "after native rewrite");
+ debug_program_log(c, "after native rewrite");
} else {
struct radeon_program_transformation transformations[] = {
{ &r300_transform_vertex_alu, 0 },
{ &radeonTransformTrigSimple, 0 }
};
- radeonLocalTransform(&compiler->Base, 2, transformations);
+ radeonLocalTransform(&c->Base, 2, transformations);
+ if (c->Base.Error)
+ return;
- debug_program_log(compiler, "after native rewrite");
+ debug_program_log(c, "after native rewrite");
/* Note: This pass has to be done seperately from ALU rewrite,
* because it needs to check every instruction.
@@ -913,9 +1034,11 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
struct radeon_program_transformation transformations2[] = {
{ &transform_nonnative_modifiers, 0 },
};
- radeonLocalTransform(&compiler->Base, 1, transformations2);
+ radeonLocalTransform(&c->Base, 1, transformations2);
+ if (c->Base.Error)
+ return;
- debug_program_log(compiler, "after emulate modifiers");
+ debug_program_log(c, "after emulate modifiers");
}
{
@@ -926,30 +1049,58 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
struct radeon_program_transformation transformations[] = {
{ &transform_source_conflicts, 0 },
};
- radeonLocalTransform(&compiler->Base, 1, transformations);
+ radeonLocalTransform(&c->Base, 1, transformations);
+ if (c->Base.Error)
+ return;
}
- debug_program_log(compiler, "after source conflict resolve");
+ debug_program_log(c, "after source conflict resolve");
- rc_dataflow_deadcode(&compiler->Base, &dataflow_outputs_mark_used, compiler);
+ rc_dataflow_deadcode(&c->Base, &dataflow_outputs_mark_used, c);
+ if (c->Base.Error)
+ return;
- debug_program_log(compiler, "after deadcode");
+ debug_program_log(c, "after deadcode");
- rc_dataflow_swizzles(&compiler->Base);
+ rc_dataflow_swizzles(&c->Base);
+ if (c->Base.Error)
+ return;
- allocate_temporary_registers(compiler);
+ debug_program_log(c, "after dataflow");
- debug_program_log(compiler, "after dataflow");
+ allocate_temporary_registers(c);
+ if (c->Base.Error)
+ return;
- translate_vertex_program(compiler);
+ debug_program_log(c, "after register allocation");
- rc_constants_copy(&compiler->code->constants, &compiler->Base.Program.Constants);
+ if (c->Base.remove_unused_constants) {
+ rc_remove_unused_constants(&c->Base,
+ &c->code->constants_remap_table);
+ if (c->Base.Error)
+ return;
- compiler->code->InputsRead = compiler->Base.Program.InputsRead;
- compiler->code->OutputsWritten = compiler->Base.Program.OutputsWritten;
+ debug_program_log(c, "after constants cleanup");
+ }
- if (compiler->Base.Debug) {
+ translate_vertex_program(c);
+ if (c->Base.Error)
+ return;
+
+ rc_constants_copy(&c->code->constants, &c->Base.Program.Constants);
+
+ c->code->InputsRead = c->Base.Program.InputsRead;
+ c->code->OutputsWritten = c->Base.Program.OutputsWritten;
+
+ if (c->Base.Debug) {
fprintf(stderr, "Final vertex program code:\n");
- r300_vertex_program_dump(compiler);
+ r300_vertex_program_dump(c);
+ }
+
+ /* Check the number of constants. */
+ if (!c->Base.Error &&
+ c->Base.Program.Constants.Count > 256) {
+ rc_error(&c->Base, "Too many constants. Max: 256, Got: %i\n",
+ c->Base.Program.Constants.Count);
}
}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
index 896246d2035..f76676fae8e 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
@@ -235,6 +235,7 @@ struct rX00_fragment_program_code {
unsigned writes_depth:1;
struct rc_constant_list constants;
+ unsigned *constants_remap_table;
};
@@ -266,6 +267,7 @@ struct r300_vertex_program_code {
int outputs[VSF_MAX_OUTPUTS];
struct rc_constant_list constants;
+ unsigned *constants_remap_table;
uint32_t InputsRead;
uint32_t OutputsWritten;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
index 7c42eb3ae57..5155b912e17 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
@@ -39,9 +39,12 @@ struct radeon_compiler {
char * ErrorMsg;
/* Hardware specification. */
- unsigned is_r500;
+ unsigned is_r500:1;
unsigned max_temp_regs;
+ /* Whether to remove unused constants and empty holes in constant space. */
+ unsigned remove_unused_constants:1;
+
/**
* Variables used internally, not be touched by callers
* of the compiler
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
index faf531b412e..acdb371de93 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
@@ -157,8 +157,12 @@ static void update_instruction(struct deadcode_state * s, struct rc_instruction
unsigned char * pused = get_used_ptr(s, inst->U.I.DstReg.File, inst->U.I.DstReg.Index);
if (pused) {
usedmask = *pused & inst->U.I.DstReg.WriteMask;
- *pused &= ~usedmask;
+ if (!inst->U.I.DstReg.RelAddr)
+ *pused &= ~usedmask;
}
+
+ if (inst->U.I.DstReg.RelAddr)
+ mark_used(s, RC_FILE_ADDRESS, 0, RC_MASK_X);
}
insts->WriteMask |= usedmask;
@@ -213,6 +217,7 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
{
struct deadcode_state s;
unsigned int nr_instructions;
+ unsigned has_temp_reladdr_src = 0;
memset(&s, 0, sizeof(s));
s.C = c;
@@ -300,6 +305,30 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name);
}
}
+
+ if (!has_temp_reladdr_src) {
+ for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
+ if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY &&
+ inst->U.I.SrcReg[i].RelAddr) {
+ /* If there is a register read from a temporary file with relative addressing,
+ * mark all preceding written registers as used. */
+ for (struct rc_instruction *ptr = inst->Prev;
+ ptr != &c->Program.Instructions;
+ ptr = ptr->Prev) {
+ if (opcode->HasDstReg &&
+ ptr->U.I.DstReg.File == RC_FILE_TEMPORARY &&
+ ptr->U.I.DstReg.WriteMask) {
+ mark_used(&s,
+ ptr->U.I.DstReg.File,
+ ptr->U.I.DstReg.Index,
+ ptr->U.I.DstReg.WriteMask);
+ }
+ }
+
+ has_temp_reladdr_src = 1;
+ }
+ }
+ }
}
update_instruction(&s, inst);
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
index 2ea830be7f9..da495a3afaa 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
@@ -95,6 +95,12 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
.IsComponentwise = 1
},
{
+ .Opcode = RC_OPCODE_DP2,
+ .Name = "DP2",
+ .NumSrcRegs = 2,
+ .HasDstReg = 1
+ },
+ {
.Opcode = RC_OPCODE_DP3,
.Name = "DP3",
.NumSrcRegs = 2,
@@ -295,6 +301,13 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
.IsComponentwise = 1
},
{
+ .Opcode = RC_OPCODE_SSG,
+ .Name = "SSG",
+ .NumSrcRegs = 1,
+ .HasDstReg = 1,
+ .IsComponentwise = 1
+ },
+ {
.Opcode = RC_OPCODE_SUB,
.Name = "SUB",
.NumSrcRegs = 2,
@@ -435,6 +448,10 @@ void rc_compute_sources_for_writemask(
case RC_OPCODE_ARL:
srcmasks[0] |= RC_MASK_X;
break;
+ case RC_OPCODE_DP2:
+ srcmasks[0] |= RC_MASK_XY;
+ srcmasks[1] |= RC_MASK_XY;
+ break;
case RC_OPCODE_DP3:
srcmasks[0] |= RC_MASK_XYZ;
srcmasks[1] |= RC_MASK_XYZ;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
index 6e18d6eb3f1..d3f639c8701 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
@@ -64,6 +64,9 @@ typedef enum {
* dst.c = d src0.c / dy */
RC_OPCODE_DDY,
+ /** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y */
+ RC_OPCODE_DP2,
+
/** scalar instruction: dst = src0.x*src1.x + src0.y*src1.y + src0.z*src1.z */
RC_OPCODE_DP3,
@@ -154,6 +157,9 @@ typedef enum {
/** vec4 instruction: dst.c = (src0.c != src1.c) ? 1.0 : 0.0 */
RC_OPCODE_SNE,
+ /** vec4 instruction: dst.c = (src0.c < 0 ?) -1 : ((src0.c > 0) : 1 : 0) */
+ RC_OPCODE_SSG,
+
/** vec4 instruction: dst.c = src0.c - src1.c */
RC_OPCODE_SUB,
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
index 407a0a55ee2..8327e9aced6 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
@@ -230,6 +230,34 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
}
+static void check_opcode_support(struct r300_fragment_program_compiler *c,
+ struct rc_sub_instruction *inst)
+{
+ const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
+
+ if (opcode->HasDstReg) {
+ if (inst->DstReg.RelAddr) {
+ rc_error(&c->Base, "Fragment program does not support relative addressing "
+ "of destination operands.\n");
+ return;
+ }
+
+ if (inst->SaturateMode == RC_SATURATE_MINUS_PLUS_ONE) {
+ rc_error(&c->Base, "Fragment program does not support signed Saturate.\n");
+ return;
+ }
+ }
+
+ for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
+ if (inst->SrcReg[i].RelAddr) {
+ rc_error(&c->Base, "Fragment program does not support relative addressing "
+ " of source operands.\n");
+ return;
+ }
+ }
+}
+
+
/**
* Translate all ALU instructions into corresponding pair instructions,
* performing no other changes.
@@ -249,6 +277,8 @@ void rc_pair_translate(struct r300_fragment_program_compiler *c)
struct rc_sub_instruction copy = inst->U.I;
+ check_opcode_support(c, &copy);
+
final_rewrite(&copy);
inst->Type = RC_INSTRUCTION_PAIR;
set_pair_instruction(c, &inst->U.P, &copy);
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
index 857aae55145..704a7bb2d23 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
@@ -216,18 +216,18 @@ static void transform_CEIL(struct radeon_compiler* c,
rc_remove_instruction(inst);
}
-static void transform_DP3(struct radeon_compiler* c,
+static void transform_DP2(struct radeon_compiler* c,
struct rc_instruction* inst)
{
struct rc_src_register src0 = inst->U.I.SrcReg[0];
struct rc_src_register src1 = inst->U.I.SrcReg[1];
- src0.Negate &= ~RC_MASK_W;
- src0.Swizzle &= ~(7 << (3 * 3));
- src0.Swizzle |= RC_SWIZZLE_ZERO << (3 * 3);
- src1.Negate &= ~RC_MASK_W;
- src1.Swizzle &= ~(7 << (3 * 3));
- src1.Swizzle |= RC_SWIZZLE_ZERO << (3 * 3);
- emit2(c, inst->Prev, RC_OPCODE_DP4, inst->U.I.SaturateMode, inst->U.I.DstReg, src0, src1);
+ src0.Negate &= ~(RC_MASK_Z | RC_MASK_W);
+ src0.Swizzle &= ~(63 << (3 * 2));
+ src0.Swizzle |= (RC_SWIZZLE_ZERO << (3 * 2)) | (RC_SWIZZLE_ZERO << (3 * 3));
+ src1.Negate &= ~(RC_MASK_Z | RC_MASK_W);
+ src1.Swizzle &= ~(63 << (3 * 2));
+ src1.Swizzle |= (RC_SWIZZLE_ZERO << (3 * 2)) | (RC_SWIZZLE_ZERO << (3 * 3));
+ emit2(c, inst->Prev, RC_OPCODE_DP3, inst->U.I.SaturateMode, inst->U.I.DstReg, src0, src1);
rc_remove_instruction(inst);
}
@@ -464,6 +464,43 @@ static void transform_SNE(struct radeon_compiler* c,
rc_remove_instruction(inst);
}
+static void transform_SSG(struct radeon_compiler* c,
+ struct rc_instruction* inst)
+{
+ /* result = sign(x)
+ *
+ * CMP tmp0, -x, 1, 0
+ * CMP tmp1, x, 1, 0
+ * ADD result, tmp0, -tmp1;
+ */
+ unsigned tmp0, tmp1;
+
+ /* 0 < x */
+ tmp0 = rc_find_free_temporary(c);
+ emit3(c, inst->Prev, RC_OPCODE_CMP, 0,
+ dstregtmpmask(tmp0, inst->U.I.DstReg.WriteMask),
+ negate(inst->U.I.SrcReg[0]),
+ builtin_one,
+ builtin_zero);
+
+ /* x < 0 */
+ tmp1 = rc_find_free_temporary(c);
+ emit3(c, inst->Prev, RC_OPCODE_CMP, 0,
+ dstregtmpmask(tmp1, inst->U.I.DstReg.WriteMask),
+ inst->U.I.SrcReg[0],
+ builtin_one,
+ builtin_zero);
+
+ /* Either both are zero, or one of them is one and the other is zero. */
+ /* result = tmp0 - tmp1 */
+ emit2(c, inst->Prev, RC_OPCODE_ADD, 0,
+ inst->U.I.DstReg,
+ srcreg(RC_FILE_TEMPORARY, tmp0),
+ negate(srcreg(RC_FILE_TEMPORARY, tmp1)));
+
+ rc_remove_instruction(inst);
+}
+
static void transform_SUB(struct radeon_compiler* c,
struct rc_instruction* inst)
{
@@ -516,6 +553,7 @@ int radeonTransformALU(
switch(inst->U.I.Opcode) {
case RC_OPCODE_ABS: transform_ABS(c, inst); return 1;
case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
+ case RC_OPCODE_DP2: transform_DP2(c, inst); return 1;
case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
case RC_OPCODE_DST: transform_DST(c, inst); return 1;
case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
@@ -530,6 +568,7 @@ int radeonTransformALU(
case RC_OPCODE_SLE: transform_SLE(c, inst); return 1;
case RC_OPCODE_SLT: transform_SLT(c, inst); return 1;
case RC_OPCODE_SNE: transform_SNE(c, inst); return 1;
+ case RC_OPCODE_SSG: transform_SSG(c, inst); return 1;
case RC_OPCODE_SUB: transform_SUB(c, inst); return 1;
case RC_OPCODE_SWZ: transform_SWZ(c, inst); return 1;
case RC_OPCODE_XPD: transform_XPD(c, inst); return 1;
@@ -577,6 +616,29 @@ static void transform_r300_vertex_CMP(struct radeon_compiler* c,
rc_remove_instruction(inst);
}
+static void transform_r300_vertex_DP2(struct radeon_compiler* c,
+ struct rc_instruction* inst)
+{
+ struct rc_instruction *next_inst = inst->Next;
+ transform_DP2(c, inst);
+ next_inst->Prev->U.I.Opcode = RC_OPCODE_DP4;
+}
+
+static void transform_r300_vertex_DP3(struct radeon_compiler* c,
+ struct rc_instruction* inst)
+{
+ struct rc_src_register src0 = inst->U.I.SrcReg[0];
+ struct rc_src_register src1 = inst->U.I.SrcReg[1];
+ src0.Negate &= ~RC_MASK_W;
+ src0.Swizzle &= ~(7 << (3 * 3));
+ src0.Swizzle |= RC_SWIZZLE_ZERO << (3 * 3);
+ src1.Negate &= ~RC_MASK_W;
+ src1.Swizzle &= ~(7 << (3 * 3));
+ src1.Swizzle |= RC_SWIZZLE_ZERO << (3 * 3);
+ emit2(c, inst->Prev, RC_OPCODE_DP4, inst->U.I.SaturateMode, inst->U.I.DstReg, src0, src1);
+ rc_remove_instruction(inst);
+}
+
static void transform_r300_vertex_fix_LIT(struct radeon_compiler* c,
struct rc_instruction* inst)
{
@@ -672,6 +734,41 @@ static void transform_r300_vertex_SLE(struct radeon_compiler* c,
inst->U.I.SrcReg[1].Negate ^= RC_MASK_XYZW;
}
+static void transform_r300_vertex_SSG(struct radeon_compiler* c,
+ struct rc_instruction* inst)
+{
+ /* result = sign(x)
+ *
+ * SLT tmp0, 0, x;
+ * SLT tmp1, x, 0;
+ * ADD result, tmp0, -tmp1;
+ */
+ unsigned tmp0, tmp1;
+
+ /* 0 < x */
+ tmp0 = rc_find_free_temporary(c);
+ emit2(c, inst->Prev, RC_OPCODE_SLT, 0,
+ dstregtmpmask(tmp0, inst->U.I.DstReg.WriteMask),
+ builtin_zero,
+ inst->U.I.SrcReg[0]);
+
+ /* x < 0 */
+ tmp1 = rc_find_free_temporary(c);
+ emit2(c, inst->Prev, RC_OPCODE_SLT, 0,
+ dstregtmpmask(tmp1, inst->U.I.DstReg.WriteMask),
+ inst->U.I.SrcReg[0],
+ builtin_zero);
+
+ /* Either both are zero, or one of them is one and the other is zero. */
+ /* result = tmp0 - tmp1 */
+ emit2(c, inst->Prev, RC_OPCODE_ADD, 0,
+ inst->U.I.DstReg,
+ srcreg(RC_FILE_TEMPORARY, tmp0),
+ negate(srcreg(RC_FILE_TEMPORARY, tmp1)));
+
+ rc_remove_instruction(inst);
+}
+
/**
* For use with radeonLocalTransform, this transforms non-native ALU
* instructions of the r300 up to r500 vertex engine.
@@ -685,7 +782,8 @@ int r300_transform_vertex_alu(
case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1;
case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
case RC_OPCODE_CMP: transform_r300_vertex_CMP(c, inst); return 1;
- case RC_OPCODE_DP3: transform_DP3(c, inst); return 1;
+ case RC_OPCODE_DP2: transform_r300_vertex_DP2(c, inst); return 1;
+ case RC_OPCODE_DP3: transform_r300_vertex_DP3(c, inst); return 1;
case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
case RC_OPCODE_LIT: transform_r300_vertex_fix_LIT(c, inst); return 1;
@@ -705,6 +803,7 @@ int r300_transform_vertex_alu(
return 1;
}
return 0;
+ case RC_OPCODE_SSG: transform_r300_vertex_SSG(c, inst); return 1;
case RC_OPCODE_SUB: transform_SUB(c, inst); return 1;
case RC_OPCODE_SWZ: transform_SWZ(c, inst); return 1;
case RC_OPCODE_XPD: transform_XPD(c, inst); return 1;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
index 9c4b65f4c00..ddce590ee66 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
@@ -117,8 +117,8 @@ int radeonTransformTEX(
struct rc_instruction * inst_rcp = NULL;
struct rc_instruction * inst_mad;
struct rc_instruction * inst_cmp;
- unsigned tmp_texsample = rc_find_free_temporary(c);
- unsigned tmp_sum = rc_find_free_temporary(c);
+ unsigned tmp_texsample;
+ unsigned tmp_sum;
unsigned tmp_recip_w = 0;
int pass, fail, tex;
@@ -126,6 +126,7 @@ int radeonTransformTEX(
struct rc_dst_register output_reg = inst->U.I.DstReg;
/* Redirect TEX to a new temp. */
+ tmp_texsample = rc_find_free_temporary(c);
inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
inst->U.I.DstReg.Index = tmp_texsample;
inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
@@ -144,6 +145,7 @@ int radeonTransformTEX(
}
/* Perspective-divide r by W (if it's TXP) and add the texture sample (see below). */
+ tmp_sum = rc_find_free_temporary(c);
inst_mad = rc_insert_new_instruction(c, inst_rcp ? inst_rcp : inst);
inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
inst_mad->U.I.DstReg.Index = tmp_sum;
@@ -199,6 +201,8 @@ int radeonTransformTEX(
inst_cmp->U.I.SrcReg[pass].File = RC_FILE_NONE;
inst_cmp->U.I.SrcReg[pass].Swizzle = RC_SWIZZLE_1111;
inst_cmp->U.I.SrcReg[fail] = shadow_ambient(compiler, inst->U.I.TexSrcUnit);
+
+ assert(tmp_texsample != tmp_sum && tmp_sum != tmp_recip_w);
}
}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c b/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c
new file mode 100644
index 00000000000..be89e9fa5b4
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010 Marek Olšák <[email protected]>
+ *
+ * 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 (including the
+ * next paragraph) 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 THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "radeon_remove_constants.h"
+
+void rc_remove_unused_constants(struct radeon_compiler *c,
+ unsigned **out_remap_table)
+{
+ unsigned char *const_used;
+ unsigned *remap_table;
+ unsigned *inv_remap_table;
+ unsigned has_rel_addr = 0;
+ unsigned is_identity = 1;
+ unsigned are_externals_remapped = 0;
+ struct rc_constant *constants = c->Program.Constants.Constants;
+
+ if (!c->Program.Constants.Count) {
+ *out_remap_table = NULL;
+ return;
+ }
+
+ const_used = malloc(c->Program.Constants.Count);
+ memset(const_used, 0, c->Program.Constants.Count);
+
+ /* Pass 1: Mark used constants. */
+ for (struct rc_instruction *inst = c->Program.Instructions.Next;
+ inst != &c->Program.Instructions; inst = inst->Next) {
+ const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+ for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
+ if (inst->U.I.SrcReg[i].File == RC_FILE_CONSTANT) {
+ if (inst->U.I.SrcReg[i].RelAddr) {
+ has_rel_addr = 1;
+ } else {
+ const_used[inst->U.I.SrcReg[i].Index] = 1;
+ }
+ }
+ }
+ }
+
+ /* Pass 2: If there is relative addressing, mark all externals as used. */
+ if (has_rel_addr) {
+ for (unsigned i = 0; i < c->Program.Constants.Count; i++)
+ if (constants[i].Type == RC_CONSTANT_EXTERNAL)
+ const_used[i] = 1;
+ }
+
+ /* Pass 3: Make the remapping table and remap constants.
+ * This pass removes unused constants simply by overwriting them by other constants. */
+ remap_table = malloc(c->Program.Constants.Count * sizeof(unsigned));
+ inv_remap_table = malloc(c->Program.Constants.Count * sizeof(unsigned));
+ unsigned new_count = 0;
+
+ for (unsigned i = 0; i < c->Program.Constants.Count; i++) {
+ if (const_used[i]) {
+ remap_table[new_count] = i;
+ inv_remap_table[i] = new_count;
+
+ if (i != new_count) {
+ if (constants[i].Type == RC_CONSTANT_EXTERNAL)
+ are_externals_remapped = 1;
+
+ constants[new_count] = constants[i];
+ is_identity = 0;
+ }
+ new_count++;
+ }
+ }
+
+ /* is_identity ==> new_count == old_count
+ * !is_identity ==> new_count < old_count */
+ assert( is_identity || new_count < c->Program.Constants.Count);
+ assert(!(has_rel_addr && are_externals_remapped));
+
+ /* Pass 4: Redirect reads of all constants to their new locations. */
+ if (!is_identity) {
+ for (struct rc_instruction *inst = c->Program.Instructions.Next;
+ inst != &c->Program.Instructions; inst = inst->Next) {
+ const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+ for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
+ if (inst->U.I.SrcReg[i].File == RC_FILE_CONSTANT) {
+ inst->U.I.SrcReg[i].Index = inv_remap_table[inst->U.I.SrcReg[i].Index];
+ }
+ }
+ }
+
+ }
+
+ /* Set the new constant count. Note that new_count may be less than
+ * Count even though the remapping function is identity. In that case,
+ * the constants have been removed at the end of the array. */
+ c->Program.Constants.Count = new_count;
+
+ if (are_externals_remapped) {
+ *out_remap_table = remap_table;
+ } else {
+ *out_remap_table = NULL;
+ free(remap_table);
+ }
+
+ free(const_used);
+ free(inv_remap_table);
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.h b/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.h
new file mode 100644
index 00000000000..0d3a26ca1ca
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_remove_constants.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Marek Olšák <[email protected]>
+ *
+ * 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 (including the
+ * next paragraph) 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 THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 RADEON_REMOVE_CONSTANTS_H
+#define RADEON_REMOVE_CONSTANTS_H
+
+#include "radeon_compiler.h"
+
+void rc_remove_unused_constants(struct radeon_compiler *c,
+ unsigned **out_remap_table);
+
+#endif
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
index 95f4306f604..7b6521c7480 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
@@ -38,7 +38,6 @@
#include "r300_fragprog_common.h"
-#include "program/prog_parameter.h"
#include "program/prog_print.h"
#include "compiler/radeon_compiler.h"
diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile
index 17915621ee4..03c17540e02 100644
--- a/src/mesa/drivers/dri/r600/Makefile
+++ b/src/mesa/drivers/dri/r600/Makefile
@@ -59,6 +59,15 @@ DRIVER_SOURCES = \
r600_texstate.c \
r600_blit.c \
r700_debug.c \
+ evergreen_context.c \
+ evergreen_state.c \
+ evergreen_tex.c \
+ evergreen_ioctl.c \
+ evergreen_render.c \
+ evergreen_chip.c \
+ evergreen_vertprog.c \
+ evergreen_fragprog.c \
+ evergreen_oglprog.c \
$(RADEON_COMMON_SOURCES) \
$(EGL_SOURCES) \
$(CS_SOURCES)
diff --git a/src/mesa/drivers/dri/r600/evergreen_chip.c b/src/mesa/drivers/dri/r600/evergreen_chip.c
new file mode 100644
index 00000000000..f925f215bcc
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_chip.c
@@ -0,0 +1,1289 @@
+/*
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#include "main/imports.h"
+#include "main/glheader.h"
+#include "main/simple_list.h"
+
+#include "r600_context.h"
+#include "r600_cmdbuf.h"
+
+#include "evergreen_chip.h"
+#include "evergreen_off.h"
+#include "evergreen_diff.h"
+#include "evergreen_fragprog.h"
+#include "evergreen_vertprog.h"
+
+#include "radeon_mipmap_tree.h"
+
+void evergreenCreateChip(context_t *context)
+{
+ EVERGREEN_CHIP_CONTEXT * evergreen =
+ (EVERGREEN_CHIP_CONTEXT*) CALLOC(sizeof(EVERGREEN_CHIP_CONTEXT));
+
+ context->pChip = (void*)evergreen;
+}
+
+#define EVERGREEN_ALLOC_STATE( ATOM, CHK, SZ, EMIT ) \
+do { \
+ context->evergreen_atoms.ATOM.cmd_size = (SZ); \
+ context->evergreen_atoms.ATOM.cmd = NULL; \
+ context->evergreen_atoms.ATOM.name = #ATOM; \
+ context->evergreen_atoms.ATOM.idx = 0; \
+ context->evergreen_atoms.ATOM.check = check_##CHK; \
+ context->evergreen_atoms.ATOM.dirty = GL_FALSE; \
+ context->evergreen_atoms.ATOM.emit = (EMIT); \
+ context->radeon.hw.max_state_size += (SZ); \
+ insert_at_tail(&context->radeon.hw.atomlist, &context->evergreen_atoms.ATOM); \
+} while (0)
+
+/*
+static void evergreen_init_query_stateobj(radeonContextPtr radeon, int SZ)
+{
+ radeon->query.queryobj.cmd_size = (SZ);
+ radeon->query.queryobj.cmd = NULL;
+ radeon->query.queryobj.name = "queryobj";
+ radeon->query.queryobj.idx = 0;
+ radeon->query.queryobj.check = check_queryobj;
+ radeon->query.queryobj.dirty = GL_FALSE;
+ radeon->query.queryobj.emit = r700SendQueryBegin;
+ radeon->hw.max_state_size += (SZ);
+ insert_at_tail(&radeon->hw.atomlist, &radeon->query.queryobj);
+}
+*/
+
+static int check_always(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ return atom->cmd_size;
+}
+
+static void evergreenSendTexState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ struct evergreen_vertex_program *vp = context->selected_vp;
+
+ struct radeon_bo *bo = NULL;
+ unsigned int i;
+ unsigned int nBorderSet = 0;
+ BATCH_LOCALS(&context->radeon);
+
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ radeonTexObj *t = evergreen->textures[i];
+
+ if (t) {
+ /* Tex resource */
+ if (!t->image_override) {
+ bo = t->mt->bo;
+ } else {
+ bo = t->bo;
+ }
+ if (bo)
+ {
+ radeon_bo_unmap(bo);
+
+ r700SyncSurf(context, bo,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM,
+ 0, TC_ACTION_ENA_bit);
+
+ BEGIN_BATCH_NO_AUTOSTATE(10 + 4);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 8));
+
+ if( (1<<i) & vp->r700AsmCode.unVetTexBits )
+ { /* vs texture */
+ R600_OUT_BATCH((i + VERT_ATTRIB_MAX + EG_SQ_FETCH_RESOURCE_VS_OFFSET) * FETCH_RESOURCE_STRIDE);
+ }
+ else
+ {
+ R600_OUT_BATCH(i * EG_FETCH_RESOURCE_STRIDE);
+ }
+
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_RESOURCE0);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_RESOURCE1);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_RESOURCE2);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_RESOURCE3);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_RESOURCE4);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_RESOURCE5);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_RESOURCE6);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_RESOURCE7);
+
+ R600_OUT_BATCH_RELOC(evergreen->textures[i]->SQ_TEX_RESOURCE2,
+ bo,
+ evergreen->textures[i]->SQ_TEX_RESOURCE2,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ R600_OUT_BATCH_RELOC(evergreen->textures[i]->SQ_TEX_RESOURCE3,
+ bo,
+ evergreen->textures[i]->SQ_TEX_RESOURCE3,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ END_BATCH();
+ COMMIT_BATCH();
+ }
+ /* Tex sampler */
+ BEGIN_BATCH_NO_AUTOSTATE(5);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3));
+
+ if( (1<<i) & vp->r700AsmCode.unVetTexBits )
+ { /* vs texture */
+ R600_OUT_BATCH((i+SQ_TEX_SAMPLER_VS_OFFSET) * 3);
+ }
+ else
+ {
+ R600_OUT_BATCH(i * 3);
+ }
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_SAMPLER0);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_SAMPLER1);
+ R600_OUT_BATCH(evergreen->textures[i]->SQ_TEX_SAMPLER2);
+
+ END_BATCH();
+ COMMIT_BATCH();
+
+ /* Tex border color */
+ if(0 == nBorderSet)
+ {
+ BEGIN_BATCH_NO_AUTOSTATE(2 + 4);
+ R600_OUT_BATCH_REGSEQ(EG_TD_PS_BORDER_COLOR_RED, 4);
+ R600_OUT_BATCH(evergreen->textures[i]->TD_PS_SAMPLER0_BORDER_RED);
+ R600_OUT_BATCH(evergreen->textures[i]->TD_PS_SAMPLER0_BORDER_GREEN);
+ R600_OUT_BATCH(evergreen->textures[i]->TD_PS_SAMPLER0_BORDER_BLUE);
+ R600_OUT_BATCH(evergreen->textures[i]->TD_PS_SAMPLER0_BORDER_ALPHA);
+ END_BATCH();
+ COMMIT_BATCH();
+
+ nBorderSet = 1;
+ }
+ }
+ }
+ }
+}
+
+static int check_evergreen_tx(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ unsigned int i, count = 0;
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ radeonTexObj *t = evergreen->textures[i];
+ if (t)
+ count++;
+ }
+ }
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+ return count * 37 + 6;
+}
+
+static void evergreenSendSQConfig(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(19);
+ //6
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SPI_CONFIG_CNTL, evergreen->evergreen_config.SPI_CONFIG_CNTL.u32All);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SPI_CONFIG_CNTL_1, evergreen->evergreen_config.SPI_CONFIG_CNTL_1.u32All);
+ //6
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_CONFIG, 4);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_CONFIG.u32All);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_1.u32All);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_2.u32All);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_3.u32All);
+ //7
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_THREAD_RESOURCE_MGMT, 5);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT.u32All);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT_2.u32All);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_1.u32All);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_2.u32All);
+ R600_OUT_BATCH(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_3.u32All);
+
+ END_BATCH();
+
+ COMMIT_BATCH();
+}
+
+extern int evergreen_getTypeSize(GLenum type);
+static void evergreenSetupVTXConstants(GLcontext * ctx,
+ void * pAos,
+ StreamDesc * pStreamDesc)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ struct radeon_aos * paos = (struct radeon_aos *)pAos;
+ unsigned int nVBsize;
+ BATCH_LOCALS(&context->radeon);
+
+ unsigned int uSQ_VTX_CONSTANT_WORD0_0;
+ unsigned int uSQ_VTX_CONSTANT_WORD1_0;
+ unsigned int uSQ_VTX_CONSTANT_WORD2_0 = 0;
+ unsigned int uSQ_VTX_CONSTANT_WORD3_0 = 0;
+ unsigned int uSQ_VTX_CONSTANT_WORD7_0 = 0;
+
+ if (!paos->bo)
+ return;
+
+ r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit);
+
+ if(0 == pStreamDesc->stride)
+ {
+ nVBsize = paos->count * pStreamDesc->size * getTypeSize(pStreamDesc->type);
+ }
+ else
+ {
+ nVBsize = (paos->count - 1) * pStreamDesc->stride
+ + pStreamDesc->size * getTypeSize(pStreamDesc->type);
+ }
+
+ //uSQ_VTX_CONSTANT_WORD0_0
+ uSQ_VTX_CONSTANT_WORD0_0 = paos->offset;
+
+ //uSQ_VTX_CONSTANT_WORD1_0
+ uSQ_VTX_CONSTANT_WORD1_0 = nVBsize;
+
+ //uSQ_VTX_CONSTANT_WORD2_0
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0,
+ pStreamDesc->stride,
+ SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift,
+ SQ_VTX_CONSTANT_WORD2_0__STRIDE_mask);
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, GetSurfaceFormat(pStreamDesc->type, pStreamDesc->size, NULL),
+ SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_shift,
+ SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_mask); // TODO : trace back api for initial data type, not only GL_FLOAT
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, 0, BASE_ADDRESS_HI_shift, BASE_ADDRESS_HI_mask); // TODO
+ if(GL_TRUE == pStreamDesc->normalize)
+ {
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_NORM,
+ SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
+ }
+ else
+ {
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_SCALED,
+ SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
+ }
+ if(1 == pStreamDesc->_signed)
+ {
+ SETbit(uSQ_VTX_CONSTANT_WORD2_0, SQ_VTX_CONSTANT_WORD2_0__FORMAT_COMP_ALL_bit);
+ }
+
+ //uSQ_VTX_CONSTANT_WORD3_0
+ SETfield(uSQ_VTX_CONSTANT_WORD3_0, SQ_SEL_X,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_X_shift,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_X_mask);
+ SETfield(uSQ_VTX_CONSTANT_WORD3_0, SQ_SEL_Y,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_Y_shift,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_Y_mask);
+ SETfield(uSQ_VTX_CONSTANT_WORD3_0, SQ_SEL_Z,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_Z_shift,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_Z_mask);
+ SETfield(uSQ_VTX_CONSTANT_WORD3_0, SQ_SEL_W,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_W_shift,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_W_mask);
+
+ //uSQ_VTX_CONSTANT_WORD7_0
+ SETfield(uSQ_VTX_CONSTANT_WORD7_0, SQ_TEX_VTX_VALID_BUFFER,
+ SQ_TEX_RESOURCE_WORD6_0__TYPE_shift, SQ_TEX_RESOURCE_WORD6_0__TYPE_mask);
+
+ BEGIN_BATCH_NO_AUTOSTATE(10 + 2);
+
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 8));
+ R600_OUT_BATCH((pStreamDesc->element + EG_SQ_FETCH_RESOURCE_VS_OFFSET) * EG_FETCH_RESOURCE_STRIDE);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD0_0);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD1_0);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD2_0);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD3_0);
+ R600_OUT_BATCH(0);
+ R600_OUT_BATCH(0);
+ R600_OUT_BATCH(0);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD7_0);
+ R600_OUT_BATCH_RELOC(uSQ_VTX_CONSTANT_WORD0_0,
+ paos->bo,
+ uSQ_VTX_CONSTANT_WORD0_0,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+
+ COMMIT_BATCH();
+}
+
+static int check_evergreen_vtx(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ int count = context->radeon.tcl.aos_count * 12;
+
+ if (count)
+ count += 6;
+
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+ return count;
+}
+
+static void evergreenSendVTX(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ struct evergreen_vertex_program *vp = (struct evergreen_vertex_program *)(context->selected_vp);
+ unsigned int i, j = 0;
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ if (context->radeon.tcl.aos_count == 0)
+ return;
+
+ BEGIN_BATCH_NO_AUTOSTATE(6);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
+ R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
+ R600_OUT_BATCH(0);
+
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
+ R600_OUT_BATCH(mmSQ_VTX_START_INST_LOC - ASIC_CTL_CONST_BASE_INDEX);
+ R600_OUT_BATCH(0);
+ END_BATCH();
+ COMMIT_BATCH();
+
+ for(i=0; i<VERT_ATTRIB_MAX; i++) {
+ if(vp->mesa_program->Base.InputsRead & (1 << i))
+ {
+ evergreenSetupVTXConstants(ctx,
+ (void*)(&context->radeon.tcl.aos[j]),
+ &(context->stream_desc[j]));
+ j++;
+ }
+ }
+}
+static void evergreenSendPA(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+ int id = 0;
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_PA_SU_HARDWARE_SCREEN_OFFSET, 0);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(22);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SC_SCREEN_SCISSOR_TL, 2);
+ R600_OUT_BATCH(evergreen->PA_SC_SCREEN_SCISSOR_TL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_SCREEN_SCISSOR_BR.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SC_WINDOW_OFFSET, 12);
+ R600_OUT_BATCH(evergreen->PA_SC_WINDOW_OFFSET.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_WINDOW_SCISSOR_TL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_WINDOW_SCISSOR_BR.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_RULE.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_0_TL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_0_BR.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_1_TL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_1_BR.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_2_TL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_2_BR.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_3_TL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_CLIPRECT_3_BR.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SC_GENERIC_SCISSOR_TL, 2);
+ R600_OUT_BATCH(evergreen->PA_SC_GENERIC_SCISSOR_TL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_GENERIC_SCISSOR_BR.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_PA_SC_EDGERULE, evergreen->PA_SC_EDGERULE.u32All);
+ END_BATCH();
+
+
+ BEGIN_BATCH_NO_AUTOSTATE(18);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SC_VPORT_SCISSOR_0_TL, 4);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_TL.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_BR.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_TL.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_BR.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SC_VPORT_ZMIN_0, 2);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_SC_VPORT_ZMIN_0.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_SC_VPORT_ZMAX_0.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_CL_VPORT_XSCALE, 6);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_CL_VPORT_XSCALE.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_CL_VPORT_XOFFSET.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_CL_VPORT_YSCALE.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_CL_VPORT_YOFFSET.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_CL_VPORT_ZSCALE.u32All);
+ R600_OUT_BATCH(evergreen->viewport[id].PA_CL_VPORT_ZOFFSET.u32All);
+ END_BATCH();
+
+
+ for (id = 0; id < EVERGREEN_MAX_UCP; id++) {
+ if (evergreen->ucp[id].enabled) {
+ BEGIN_BATCH_NO_AUTOSTATE(6);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_CL_UCP_0_X + (4 * id), 4);
+ R600_OUT_BATCH(evergreen->ucp[id].PA_CL_UCP_0_X.u32All);
+ R600_OUT_BATCH(evergreen->ucp[id].PA_CL_UCP_0_Y.u32All);
+ R600_OUT_BATCH(evergreen->ucp[id].PA_CL_UCP_0_Z.u32All);
+ R600_OUT_BATCH(evergreen->ucp[id].PA_CL_UCP_0_W.u32All);
+ END_BATCH();
+ }
+ }
+
+ BEGIN_BATCH_NO_AUTOSTATE(42);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_CL_CLIP_CNTL, 5);
+ R600_OUT_BATCH(evergreen->PA_CL_CLIP_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_SC_MODE_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->PA_CL_VTE_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->PA_CL_VS_OUT_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->PA_CL_NANINF_CNTL.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SU_POINT_SIZE, 3);
+ R600_OUT_BATCH(evergreen->PA_SU_POINT_SIZE.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_POINT_MINMAX.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_LINE_CNTL.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SC_MODE_CNTL_0, 2);
+ R600_OUT_BATCH(evergreen->PA_SC_MODE_CNTL_0.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_MODE_CNTL_1.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SU_POLY_OFFSET_DB_FMT_CNTL, 6);
+ R600_OUT_BATCH(evergreen->PA_SU_POLY_OFFSET_DB_FMT_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_POLY_OFFSET_CLAMP.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_POLY_OFFSET_FRONT_SCALE.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_POLY_OFFSET_FRONT_OFFSET.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_POLY_OFFSET_BACK_SCALE.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_POLY_OFFSET_BACK_OFFSET.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_PA_SC_LINE_CNTL, 16);
+ R600_OUT_BATCH(evergreen->PA_SC_LINE_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_CONFIG.u32All);
+ R600_OUT_BATCH(evergreen->PA_SU_VTX_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->PA_CL_GB_VERT_CLIP_ADJ.u32All);
+ R600_OUT_BATCH(evergreen->PA_CL_GB_VERT_DISC_ADJ.u32All);
+ R600_OUT_BATCH(evergreen->PA_CL_GB_HORZ_CLIP_ADJ.u32All);
+ R600_OUT_BATCH(evergreen->PA_CL_GB_HORZ_DISC_ADJ.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_SAMPLE_LOCS_0.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_SAMPLE_LOCS_1.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_SAMPLE_LOCS_2.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_SAMPLE_LOCS_3.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_SAMPLE_LOCS_4.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_SAMPLE_LOCS_5.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_SAMPLE_LOCS_6.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_SAMPLE_LOCS_7.u32All);
+ R600_OUT_BATCH(evergreen->PA_SC_AA_MASK.u32All);
+
+ END_BATCH();
+
+ COMMIT_BATCH();
+}
+static void evergreenSendTP(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ /*
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ COMMIT_BATCH();
+ */
+}
+
+static void evergreenSendPSresource(GLcontext *ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct radeon_bo * pbo;
+
+ struct radeon_bo * pbo_const;
+
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ pbo = (struct radeon_bo *)evergreenGetActiveFpShaderBo(GL_CONTEXT(context));
+
+ if (!pbo)
+ return;
+
+ r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_START_PS, 1);
+ R600_OUT_BATCH(evergreen->ps.SQ_PGM_START_PS.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->ps.SQ_PGM_START_PS.u32All,
+ pbo,
+ evergreen->ps.SQ_PGM_START_PS.u32All,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SQ_LOOP_CONST_0, 0x01000FFF);
+ END_BATCH();
+
+ pbo_const = (struct radeon_bo *)(context->fp_Constbo);
+
+ if(NULL != pbo_const)
+ {
+ r700SyncSurf(context, pbo_const, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+
+ if(evergreen->ps.num_consts < 4)
+ {
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SQ_ALU_CONST_BUFFER_SIZE_PS_0, 1);
+ }
+ else
+ {
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SQ_ALU_CONST_BUFFER_SIZE_PS_0, (evergreen->ps.num_consts * 4)/16 );
+ }
+
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_ALU_CONST_CACHE_PS_0, 1);
+ R600_OUT_BATCH(context->fp_bo_offset >> 8);
+ R600_OUT_BATCH_RELOC(0,
+ pbo_const,
+ 0,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+ }
+
+ COMMIT_BATCH();
+}
+
+static void evergreenSendVSresource(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct radeon_bo * pbo;
+
+ struct radeon_bo * pbo_const;
+
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ pbo = (struct radeon_bo *)evergreenGetActiveVpShaderBo(GL_CONTEXT(context));
+
+ if (!pbo)
+ return;
+
+ r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_START_VS, 1);
+ R600_OUT_BATCH(evergreen->vs.SQ_PGM_START_VS.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->vs.SQ_PGM_START_VS.u32All,
+ pbo,
+ evergreen->vs.SQ_PGM_START_VS.u32All,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGVAL((EG_SQ_LOOP_CONST_0 + 32*1), 0x0100000F); //consts == 1
+ //EVERGREEN_OUT_BATCH_REGVAL((EG_SQ_LOOP_CONST_0 + (SQ_LOOP_CONST_vs<2)), 0x0100000F);
+ END_BATCH();
+
+ pbo_const = (struct radeon_bo *)(context->vp_Constbo);
+
+ if(NULL != pbo_const)
+ {
+ r700SyncSurf(context, pbo_const, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+
+ if(evergreen->vs.num_consts < 4)
+ {
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SQ_ALU_CONST_BUFFER_SIZE_VS_0, 1);
+ }
+ else
+ {
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SQ_ALU_CONST_BUFFER_SIZE_VS_0, (evergreen->vs.num_consts * 4)/16 );
+ }
+
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_ALU_CONST_CACHE_VS_0, 1);
+ R600_OUT_BATCH(context->vp_bo_offset >> 8);
+ R600_OUT_BATCH_RELOC(0,
+ pbo_const,
+ 0,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+ }
+
+ COMMIT_BATCH();
+}
+
+static void evergreenSendSQ(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ evergreenSendPSresource(ctx); //16 entries now
+
+ BEGIN_BATCH_NO_AUTOSTATE(77);
+
+ //34
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_VTX_SEMANTIC_0, 32);
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_0.u32All); //// // = 0x28380, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_1.u32All); //// // = 0x28384, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_2.u32All); //// // = 0x28388, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_3.u32All); //// // = 0x2838C, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_4.u32All); //// // = 0x28390, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_5.u32All); //// // = 0x28394, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_6.u32All); //// // = 0x28398, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_7.u32All); //// // = 0x2839C, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_8.u32All); //// // = 0x283A0, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_9.u32All); //// // = 0x283A4, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_10.u32All); //// // = 0x283A8, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_11.u32All); //// // = 0x283AC, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_12.u32All); //// // = 0x283B0, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_13.u32All); //// // = 0x283B4, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_14.u32All); //// // = 0x283B8, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_15.u32All); //// // = 0x283BC, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_16.u32All); //// // = 0x283C0, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_17.u32All); //// // = 0x283C4, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_18.u32All); //// // = 0x283C8, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_19.u32All); //// // = 0x283CC, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_20.u32All); //// // = 0x283D0, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_21.u32All); //// // = 0x283D4, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_22.u32All); //// // = 0x283D8, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_23.u32All); //// // = 0x283DC, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_24.u32All); //// // = 0x283E0, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_25.u32All); //// // = 0x283E4, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_26.u32All); //// // = 0x283E8, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_27.u32All); //// // = 0x283EC, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_28.u32All); //// // = 0x283F0, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_29.u32All); //// // = 0x283F4, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_30.u32All); //// // = 0x283F8, // SAME
+ R600_OUT_BATCH(evergreen->SQ_VTX_SEMANTIC_31.u32All); //// // = 0x283FC, // SAME
+
+
+ //3
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_DYN_GPR_RESOURCE_LIMIT_1, 1);
+ R600_OUT_BATCH(evergreen->SQ_DYN_GPR_RESOURCE_LIMIT_1.u32All);//// // = 0x28838, //
+
+ //5
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_RESOURCES_PS, 3);
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_PS.u32All); //// // = 0x28844, // DIFF 0x28850
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_2_PS.u32All); //// // = 0x28848, //
+ R600_OUT_BATCH(evergreen->SQ_PGM_EXPORTS_PS.u32All); //// // = 0x2884C, // SAME 0x28854
+
+ //4
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_RESOURCES_VS, 2);
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_VS.u32All);//// // = 0x28860, // DIFF 0x28868
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_2_VS.u32All); //// // = 0x28864, //
+
+ //5
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_RESOURCES_GS, 2);
+ /*
+ R600_OUT_BATCH(evergreen->SQ_PGM_START_GS.u32All); //// // = 0x28874, // SAME 0x2886C
+ */
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_GS.u32All); //// // = 0x28878, // DIFF 0x2887C
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_2_GS.u32All); //// // = 0x2887C, //
+
+ //5
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_RESOURCES_ES, 2);
+ /*
+ R600_OUT_BATCH(evergreen->SQ_PGM_START_ES.u32All); //// // = 0x2888C, // SAME 0x28880
+ */
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_ES.u32All); //// // = 0x28890, // DIFF
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_2_ES.u32All); //// // = 0x28894, //
+
+ //4
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_RESOURCES_FS, 1);
+ /*
+ R600_OUT_BATCH(evergreen->SQ_PGM_START_FS.u32All); //// // = 0x288A4, // SAME 0x28894
+ */
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_FS.u32All); //// // = 0x288A8, // DIFF 0x288A4
+
+ //3
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_RESOURCES_2_HS, 1);
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_2_HS.u32All);//// // = 0x288C0, //
+
+ //3
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_PGM_RESOURCES_2_LS, 1);
+ R600_OUT_BATCH(evergreen->SQ_PGM_RESOURCES_2_LS.u32All); //// // = 0x288D8, //
+
+ //3
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_LDS_ALLOC_PS, 1);
+ R600_OUT_BATCH(evergreen->SQ_LDS_ALLOC_PS.u32All); //// // = 0x288EC, //
+
+ //8
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_ESGS_RING_ITEMSIZE, 6);
+ R600_OUT_BATCH(evergreen->SQ_ESGS_RING_ITEMSIZE.u32All); //// // = 0x28900, // SAME 0x288A8
+ R600_OUT_BATCH(evergreen->SQ_GSVS_RING_ITEMSIZE.u32All); //// // = 0x28904, // SAME 0x288AC
+ R600_OUT_BATCH(evergreen->SQ_ESTMP_RING_ITEMSIZE.u32All); //// // = 0x28908, // SAME 0x288B0
+ R600_OUT_BATCH(evergreen->SQ_GSTMP_RING_ITEMSIZE.u32All); //// // = 0x2890C, // SAME 0x288B4
+ R600_OUT_BATCH(evergreen->SQ_VSTMP_RING_ITEMSIZE.u32All); //// // = 0x28910, // SAME 0x288B8
+ R600_OUT_BATCH(evergreen->SQ_PSTMP_RING_ITEMSIZE.u32All); //// // = 0x28914, // SAME 0x288BC
+
+ //3
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SQ_GS_VERT_ITEMSIZE, 1);
+ R600_OUT_BATCH(evergreen->SQ_GS_VERT_ITEMSIZE.u32All); //// // = 0x2891C, // SAME 0x288C8
+
+ END_BATCH();
+
+ COMMIT_BATCH();
+
+}
+static void evergreenSendSPI(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(59);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SPI_VS_OUT_ID_0, 10);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_0.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_1.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_2.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_3.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_4.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_5.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_6.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_7.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_8.u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_ID_9.u32All);
+
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_SPI_PS_INPUT_CNTL_0, 45);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[0].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[1].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[2].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[3].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[4].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[5].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[6].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[7].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[8].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[9].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[10].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[11].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[12].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[13].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[14].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[15].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[16].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[17].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[18].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[19].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[20].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[21].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[22].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[23].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[24].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[25].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[26].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[27].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[28].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[29].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[30].u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_INPUT_CNTL[31].u32All);
+ R600_OUT_BATCH(evergreen->SPI_VS_OUT_CONFIG.u32All);
+ R600_OUT_BATCH(evergreen->SPI_THREAD_GROUPING.u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_IN_CONTROL_0.u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_IN_CONTROL_1.u32All);
+ R600_OUT_BATCH(evergreen->SPI_INTERP_CONTROL_0.u32All);
+ R600_OUT_BATCH(evergreen->SPI_INPUT_Z.u32All);
+ R600_OUT_BATCH(evergreen->SPI_FOG_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->SPI_BARYC_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->SPI_PS_IN_CONTROL_2.u32All);
+ R600_OUT_BATCH(evergreen->SPI_COMPUTE_INPUT_CNTL.u32All);
+ R600_OUT_BATCH(evergreen->SPI_COMPUTE_NUM_THREAD_X.u32All);
+ R600_OUT_BATCH(evergreen->SPI_COMPUTE_NUM_THREAD_Y.u32All);
+ R600_OUT_BATCH(evergreen->SPI_COMPUTE_NUM_THREAD_Z.u32All);
+
+ END_BATCH();
+
+ COMMIT_BATCH();
+}
+static void evergreenSendSX(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(9);
+
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SX_MISC, evergreen->SX_MISC.u32All);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SX_ALPHA_TEST_CONTROL, evergreen->SX_ALPHA_TEST_CONTROL.u32All);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_SX_ALPHA_REF, evergreen->SX_ALPHA_REF.u32All);
+
+ END_BATCH();
+
+ COMMIT_BATCH();
+}
+
+static void evergreenSetDepthTarget(context_t *context)
+{
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct radeon_renderbuffer *rrb;
+ unsigned int nPitchInPixel;
+
+ rrb = radeon_get_depthbuffer(&context->radeon);
+ if (!rrb)
+ {
+ return;
+ }
+
+ EVERGREEN_STATECHANGE(context, db);
+
+ evergreen->DB_DEPTH_SIZE.u32All = 0;
+
+ SETfield(evergreen->DB_DEPTH_SIZE.u32All, (nPitchInPixel/8)-1,
+ EG_DB_DEPTH_SIZE__PITCH_TILE_MAX_shift,
+ EG_DB_DEPTH_SIZE__PITCH_TILE_MAX_mask);
+ SETfield(evergreen->DB_DEPTH_SIZE.u32All, (context->radeon.radeonScreen->driScreen->fbHeight/8)-1,
+ EG_DB_DEPTH_SIZE__HEIGHT_TILE_MAX_shift,
+ EG_DB_DEPTH_SIZE__HEIGHT_TILE_MAX_mask);
+ evergreen->DB_DEPTH_SLICE.u32All = ( (nPitchInPixel * context->radeon.radeonScreen->driScreen->fbHeight)/64 )-1;
+
+ if(4 == rrb->cpp)
+ {
+ SETfield(evergreen->DB_Z_INFO.u32All, DEPTH_8_24,
+ EG_DB_Z_INFO__FORMAT_shift,
+ EG_DB_Z_INFO__FORMAT_mask);
+ }
+ else
+ {
+ SETfield(evergreen->DB_Z_INFO.u32All, DEPTH_16,
+ EG_DB_Z_INFO__FORMAT_shift,
+ EG_DB_Z_INFO__FORMAT_mask);
+ }
+ SETfield(evergreen->DB_Z_INFO.u32All, ARRAY_1D_TILED_THIN1,
+ EG_DB_Z_INFO__ARRAY_MODE_shift,
+ EG_DB_Z_INFO__ARRAY_MODE_mask);
+}
+
+static void evergreenSendDB(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct radeon_renderbuffer *rrb;
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ evergreenSetDepthTarget(context);
+
+ //8
+ BEGIN_BATCH_NO_AUTOSTATE(7);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_DB_RENDER_CONTROL, 5);
+ R600_OUT_BATCH(evergreen->DB_RENDER_CONTROL.u32All);
+ R600_OUT_BATCH(evergreen->DB_COUNT_CONTROL.u32All);
+ R600_OUT_BATCH(evergreen->DB_DEPTH_VIEW.u32All);
+ R600_OUT_BATCH(evergreen->DB_RENDER_OVERRIDE.u32All);
+ R600_OUT_BATCH(evergreen->DB_RENDER_OVERRIDE2.u32All);
+ /*
+ R600_OUT_BATCH(evergreen->DB_HTILE_DATA_BASE.u32All);
+ */
+ END_BATCH();
+
+ //4
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_DB_STENCIL_CLEAR, 2);
+ R600_OUT_BATCH(evergreen->DB_STENCIL_CLEAR.u32All);
+ R600_OUT_BATCH(evergreen->DB_DEPTH_CLEAR.u32All);
+ END_BATCH();
+
+ //4
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_DB_DEPTH_SIZE, 2);
+ R600_OUT_BATCH(evergreen->DB_DEPTH_SIZE.u32All);
+ R600_OUT_BATCH(evergreen->DB_DEPTH_SLICE.u32All);
+ END_BATCH();
+
+ //3
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_DEPTH_CONTROL, evergreen->DB_DEPTH_CONTROL.u32All);
+ END_BATCH();
+
+ //3
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_SHADER_CONTROL, evergreen->DB_SHADER_CONTROL.u32All);
+ END_BATCH();
+
+ //5
+ BEGIN_BATCH_NO_AUTOSTATE(5);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_DB_SRESULTS_COMPARE_STATE0, 3);
+ R600_OUT_BATCH(evergreen->DB_SRESULTS_COMPARE_STATE0.u32All);
+ R600_OUT_BATCH(evergreen->DB_SRESULTS_COMPARE_STATE1.u32All);
+ R600_OUT_BATCH(evergreen->DB_PRELOAD_CONTROL.u32All);
+ END_BATCH();
+
+ //3
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_ALPHA_TO_MASK, evergreen->DB_ALPHA_TO_MASK.u32All);
+ END_BATCH();
+
+ rrb = radeon_get_depthbuffer(&context->radeon);
+ if( (rrb != NULL) && (rrb->bo != NULL) )
+ {
+ //5
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_Z_INFO, evergreen->DB_Z_INFO.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->DB_Z_INFO.u32All,
+ rrb->bo,
+ evergreen->DB_Z_INFO.u32All,
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+
+ //5
+ if((evergreen->DB_DEPTH_CONTROL.u32All & Z_ENABLE_bit) > 0)
+ {
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_Z_READ_BASE, evergreen->DB_Z_READ_BASE.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->DB_Z_READ_BASE.u32All,
+ rrb->bo,
+ evergreen->DB_Z_READ_BASE.u32All,
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+ }
+ //5
+ if((evergreen->DB_DEPTH_CONTROL.u32All & Z_WRITE_ENABLE_bit) > 0)
+ {
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_Z_WRITE_BASE, evergreen->DB_Z_READ_BASE.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->DB_Z_WRITE_BASE.u32All,
+ rrb->bo,
+ evergreen->DB_Z_WRITE_BASE.u32All,
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+ }
+ }
+/*
+ if (ctx->DrawBuffer)
+ {
+ rrb = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
+
+ if((rrb != NULL) && (rrb->bo != NULL))
+ {
+ //5
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_STENCIL_INFO, evergreen->DB_Z_INFO.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->DB_STENCIL_INFO.u32All,
+ rrb->bo,
+ evergreen->DB_STENCIL_INFO.u32All,
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+
+ //10
+ if((evergreen->DB_DEPTH_CONTROL.u32All & STENCIL_ENABLE_bit) > 0)
+ {
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_STENCIL_READ_BASE, evergreen->DB_STENCIL_READ_BASE.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->DB_STENCIL_READ_BASE.u32All,
+ rrb->bo,
+ evergreen->DB_STENCIL_READ_BASE.u32All,
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_DB_STENCIL_WRITE_BASE, evergreen->DB_STENCIL_WRITE_BASE.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->DB_STENCIL_WRITE_BASE.u32All,
+ rrb->bo,
+ evergreen->DB_STENCIL_WRITE_BASE.u32All,
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+ }
+ }
+ }
+*/
+ COMMIT_BATCH();
+}
+
+static void evergreenSetRenderTarget(context_t *context, int id)
+{
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ struct radeon_renderbuffer *rrb;
+ unsigned int nPitchInPixel;
+
+ rrb = radeon_get_colorbuffer(&context->radeon);
+ if (!rrb || !rrb->bo) {
+ return;
+ }
+
+ EVERGREEN_STATECHANGE(context, cb);
+
+ /* addr */
+ evergreen->render_target[id].CB_COLOR0_BASE.u32All = context->radeon.state.color.draw_offset / 256;
+
+ /* pitch */
+ nPitchInPixel = rrb->pitch/rrb->cpp;
+
+ SETfield(evergreen->render_target[id].CB_COLOR0_PITCH.u32All, (nPitchInPixel/8)-1,
+ EG_CB_COLOR0_PITCH__TILE_MAX_shift,
+ EG_CB_COLOR0_PITCH__TILE_MAX_mask);
+
+ /* skice */
+ SETfield(evergreen->render_target[id].CB_COLOR0_SLICE.u32All,
+ //( (nPitchInPixel * context->radeon.radeonScreen->driScreen->fbHeight)/64 )-1,
+ ( (nPitchInPixel * 240)/64 )-1,
+ EG_CB_COLOR0_SLICE__TILE_MAX_shift,
+ EG_CB_COLOR0_SLICE__TILE_MAX_mask);
+
+ /* CB_COLOR0_ATTRIB */ /* TODO : for z clear, this should be set to 0 */
+ SETbit(evergreen->render_target[id].CB_COLOR0_ATTRIB.u32All,
+ EG_CB_COLOR0_ATTRIB__NON_DISP_TILING_ORDER_bit);
+
+ /* CB_COLOR0_INFO */
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ ENDIAN_NONE,
+ EG_CB_COLOR0_INFO__ENDIAN_shift,
+ EG_CB_COLOR0_INFO__ENDIAN_mask);
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ ARRAY_LINEAR_GENERAL,
+ EG_CB_COLOR0_INFO__ARRAY_MODE_shift,
+ EG_CB_COLOR0_INFO__ARRAY_MODE_mask);
+ if(4 == rrb->cpp)
+ {
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ COLOR_8_8_8_8,
+ EG_CB_COLOR0_INFO__FORMAT_shift,
+ EG_CB_COLOR0_INFO__FORMAT_mask);
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ SWAP_ALT, //SWAP_STD
+ EG_CB_COLOR0_INFO__COMP_SWAP_shift,
+ EG_CB_COLOR0_INFO__COMP_SWAP_mask);
+ }
+ else
+ {
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ COLOR_5_6_5,
+ EG_CB_COLOR0_INFO__FORMAT_shift,
+ EG_CB_COLOR0_INFO__FORMAT_mask);
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ SWAP_ALT_REV,
+ EG_CB_COLOR0_INFO__COMP_SWAP_shift,
+ EG_CB_COLOR0_INFO__COMP_SWAP_mask);
+ }
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ 1,
+ EG_CB_COLOR0_INFO__SOURCE_FORMAT_shift,
+ EG_CB_COLOR0_INFO__SOURCE_FORMAT_mask);
+ SETbit(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ EG_CB_COLOR0_INFO__BLEND_CLAMP_bit);
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ NUMBER_UNORM,
+ EG_CB_COLOR0_INFO__NUMBER_TYPE_shift,
+ EG_CB_COLOR0_INFO__NUMBER_TYPE_mask);
+
+ evergreen->render_target[id].CB_COLOR0_VIEW.u32All = 0;
+ evergreen->render_target[id].CB_COLOR0_CMASK.u32All = 0;
+ evergreen->render_target[id].CB_COLOR0_FMASK.u32All = 0;
+ evergreen->render_target[id].CB_COLOR0_FMASK_SLICE.u32All = 0;
+
+ evergreen->render_target[id].enabled = GL_TRUE;
+}
+
+static void evergreenSendCB(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct radeon_renderbuffer *rrb;
+ BATCH_LOCALS(&context->radeon);
+ int id = 0;
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ rrb = radeon_get_colorbuffer(&context->radeon);
+ if (!rrb || !rrb->bo) {
+ return;
+ }
+
+ evergreenSetRenderTarget(context, 0);
+
+ if (!evergreen->render_target[id].enabled)
+ return;
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_CB_COLOR0_BASE + (4 * id), 1);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_BASE.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->render_target[id].CB_COLOR0_BASE.u32All,
+ rrb->bo,
+ evergreen->render_target[id].CB_COLOR0_BASE.u32All,
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_CB_COLOR0_INFO, evergreen->render_target[id].CB_COLOR0_INFO.u32All);
+ R600_OUT_BATCH_RELOC(evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ rrb->bo,
+ evergreen->render_target[id].CB_COLOR0_INFO.u32All,
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(5);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_CB_COLOR0_PITCH, 3);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_PITCH.u32All);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_SLICE.u32All);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_VIEW.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_CB_COLOR0_ATTRIB, 2);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_ATTRIB.u32All);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_DIM.u32All);
+ /*
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_CMASK.u32All);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_CMASK_SLICE.u32All);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_FMASK.u32All);
+ R600_OUT_BATCH(evergreen->render_target[id].CB_COLOR0_FMASK_SLICE.u32All);
+ */
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_CB_TARGET_MASK, 2);
+ R600_OUT_BATCH(evergreen->CB_TARGET_MASK.u32All);
+ R600_OUT_BATCH(evergreen->CB_SHADER_MASK.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(5);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_CB_BLEND_RED, 3);
+ R600_OUT_BATCH(evergreen->CB_BLEND_RED.u32All);
+ R600_OUT_BATCH(evergreen->CB_BLEND_GREEN.u32All);
+ R600_OUT_BATCH(evergreen->CB_BLEND_BLUE.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(9);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_CB_BLEND_ALPHA, evergreen->CB_BLEND_ALPHA.u32All);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_CB_BLEND0_CONTROL, evergreen->CB_BLEND0_CONTROL.u32All);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_CB_COLOR_CONTROL, evergreen->CB_COLOR_CONTROL.u32All);
+ END_BATCH();
+
+ COMMIT_BATCH();
+}
+static void evergreenSendCP(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ //first to send
+ //r700Start3D
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_CONTEXT_CONTROL, 1)); //IT_CONTEXT_CONTROL 0x28
+ R600_OUT_BATCH(0x80000000);
+ R600_OUT_BATCH(0x80000000);
+ END_BATCH();
+
+ COMMIT_BATCH();
+}
+static void evergreenSendVGT(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+/* moved to draw:
+ VGT_DRAW_INITIATOR
+ VGT_INDEX_TYPE
+ VGT_PRIMITIVE_TYPE
+*/
+ BEGIN_BATCH_NO_AUTOSTATE(5);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_VGT_MAX_VTX_INDX, 3);
+ R600_OUT_BATCH(evergreen->VGT_MAX_VTX_INDX.u32All);
+ R600_OUT_BATCH(evergreen->VGT_MIN_VTX_INDX.u32All);
+ R600_OUT_BATCH(evergreen->VGT_INDX_OFFSET.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(6);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_VGT_OUTPUT_PATH_CNTL, evergreen->VGT_OUTPUT_PATH_CNTL.u32All);
+
+ EVERGREEN_OUT_BATCH_REGVAL(EG_VGT_GS_MODE, evergreen->VGT_GS_MODE.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_VGT_PRIMITIVEID_EN, 1);
+ R600_OUT_BATCH(evergreen->VGT_PRIMITIVEID_EN.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_VGT_INSTANCE_STEP_RATE_0, 2);
+ R600_OUT_BATCH(evergreen->VGT_INSTANCE_STEP_RATE_0.u32All);
+ R600_OUT_BATCH(evergreen->VGT_INSTANCE_STEP_RATE_1.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_VGT_REUSE_OFF, 2);
+ R600_OUT_BATCH(evergreen->VGT_REUSE_OFF.u32All);
+ R600_OUT_BATCH(evergreen->VGT_VTX_CNT_EN.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ EVERGREEN_OUT_BATCH_REGVAL(EG_VGT_SHADER_STAGES_EN, evergreen->VGT_SHADER_STAGES_EN.u32All);
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ EVERGREEN_OUT_BATCH_REGSEQ(EG_VGT_STRMOUT_CONFIG, 2);
+ R600_OUT_BATCH(evergreen->VGT_STRMOUT_CONFIG.u32All);
+ R600_OUT_BATCH(evergreen->VGT_STRMOUT_BUFFER_CONFIG.u32All);
+ END_BATCH();
+
+ COMMIT_BATCH();
+}
+
+static void evergreenSendTIMESTAMP(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+}
+
+void evergreenInitAtoms(context_t *context)
+{
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %p\n", __func__, context);
+ context->radeon.hw.max_state_size = 10 + 5 + 14 + 3; /* start 3d, idle, cb/db flush, 3 for time stamp */
+
+ /* Setup the atom linked list */
+ make_empty_list(&context->radeon.hw.atomlist);
+ context->radeon.hw.atomlist.name = "atom-list";
+
+ EVERGREEN_ALLOC_STATE(init, always, 19, evergreenSendSQConfig);
+
+ //make sure send first
+ EVERGREEN_ALLOC_STATE(cp, always, 3, evergreenSendCP);
+
+ EVERGREEN_ALLOC_STATE(vtx, evergreen_vtx, (6 + (VERT_ATTRIB_MAX * 12)), evergreenSendVTX);
+ EVERGREEN_ALLOC_STATE(pa, always, 124, evergreenSendPA);
+ EVERGREEN_ALLOC_STATE(tp, always, 0, evergreenSendTP);
+ EVERGREEN_ALLOC_STATE(sq, always, 86, evergreenSendSQ); /* 85 */
+ EVERGREEN_ALLOC_STATE(vs, always, 16, evergreenSendVSresource);
+ EVERGREEN_ALLOC_STATE(spi, always, 59, evergreenSendSPI);
+ EVERGREEN_ALLOC_STATE(sx, always, 9, evergreenSendSX);
+ EVERGREEN_ALLOC_STATE(tx, evergreen_tx, (R700_TEXTURE_NUMBERUNITS * (21+5) + 6), evergreenSendTexState); /* 21 for resource, 5 for sampler */
+ EVERGREEN_ALLOC_STATE(db, always, 60, evergreenSendDB);
+ EVERGREEN_ALLOC_STATE(cb, always, 35, evergreenSendCB);
+ EVERGREEN_ALLOC_STATE(vgt, always, 29, evergreenSendVGT);
+ EVERGREEN_ALLOC_STATE(timestamp, always, 3, evergreenSendTIMESTAMP);
+
+ //evergreen_init_query_stateobj(&context->radeon, 6 * 2);
+
+ context->radeon.hw.is_dirty = GL_TRUE;
+ context->radeon.hw.all_dirty = GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/r600/evergreen_chip.h b/src/mesa/drivers/dri/r600/evergreen_chip.h
new file mode 100644
index 00000000000..2ea5cd213c7
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_chip.h
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#ifndef _EVERGREEN_CHIP_H_
+#define _EVERGREEN_CHIP_H_
+
+#include "r700_chip.h"
+
+#define EVERGREEN_MAX_DX9_CONSTS 256
+#define EVERGREEN_MAX_SHADER_EXPORTS 32
+#define EVERGREEN_MAX_VIEWPORTS 16
+
+typedef struct _EVERGREEN_VIEWPORT_STATE
+{
+ union UINT_FLOAT PA_SC_VPORT_SCISSOR_0_TL; ////0,1 // = 0x28250, // DIFF
+ union UINT_FLOAT PA_SC_VPORT_SCISSOR_0_BR; ////0,1 // = 0x28254, // DIFF
+ union UINT_FLOAT PA_SC_VPORT_ZMIN_0; ////0 // = 0x282D0, // SAME
+ union UINT_FLOAT PA_SC_VPORT_ZMAX_0; ////0 // = 0x282D4, // SAME
+ union UINT_FLOAT PA_CL_VPORT_XSCALE; //// // = 0x2843C, // SAME
+ union UINT_FLOAT PA_CL_VPORT_XOFFSET; //// // = 0x28440, // SAME
+ union UINT_FLOAT PA_CL_VPORT_YSCALE; //// // = 0x28444, // SAME
+ union UINT_FLOAT PA_CL_VPORT_YOFFSET; //// // = 0x28448, // SAME
+ union UINT_FLOAT PA_CL_VPORT_ZSCALE; //// // = 0x2844C, // SAME
+ union UINT_FLOAT PA_CL_VPORT_ZOFFSET; //// // = 0x28450, // SAME
+ GLboolean enabled;
+ GLboolean dirty;
+} EVERGREEN_VIEWPORT_STATE;
+
+#define EVERGREEN_MAX_UCP 6
+
+typedef struct _EVERGREEN_UCP_STATE
+{
+ union UINT_FLOAT PA_CL_UCP_0_X; // = 0x285BC, // SAME 0x28E20
+ union UINT_FLOAT PA_CL_UCP_0_Y; // = 0x285C0, // SAME 0x28E24
+ union UINT_FLOAT PA_CL_UCP_0_Z; // = 0x285C4, // SAME 0x28E28
+ union UINT_FLOAT PA_CL_UCP_0_W; // = 0x285C8, // SAME 0x28E2C
+ GLboolean enabled;
+ GLboolean dirty;
+} EVERGREEN_UCP_STATE;
+
+#define EVERGREEN_MAX_RENDER_TARGETS 12
+
+typedef struct _EVERGREEN_RENDER_TARGET_STATE
+{
+ union UINT_FLOAT CB_COLOR0_BASE; ////0 // = 0x28C60, // SAME 0x28040
+ union UINT_FLOAT CB_COLOR0_PITCH; ////0 // = 0x28C64, //
+ union UINT_FLOAT CB_COLOR0_SLICE; ////0 // = 0x28C68, //
+ union UINT_FLOAT CB_COLOR0_VIEW; ////0 // = 0x28C6C, // SAME 0x28080
+ union UINT_FLOAT CB_COLOR0_INFO; ////0,1,2,3,4,5,6,78,9,10,11 // = 0x28C70, // DIFF 0x280A0
+ union UINT_FLOAT CB_COLOR0_ATTRIB; ////0 // = 0x28C74, //
+ union UINT_FLOAT CB_COLOR0_DIM; // = 0x28C78, //
+ union UINT_FLOAT CB_COLOR0_CMASK; ////0 // = 0x28C7C, //
+ union UINT_FLOAT CB_COLOR0_CMASK_SLICE; ////0 // = 0x28C80, //
+ union UINT_FLOAT CB_COLOR0_FMASK; ////0 // = 0x28C84, //
+ union UINT_FLOAT CB_COLOR0_FMASK_SLICE; ////0 // = 0x28C88, //
+ union UINT_FLOAT CB_COLOR0_CLEAR_WORD0; // = 0x28C8C, //
+ union UINT_FLOAT CB_COLOR0_CLEAR_WORD1; // = 0x28C90, //
+ union UINT_FLOAT CB_COLOR0_CLEAR_WORD2; // = 0x28C94, //
+ union UINT_FLOAT CB_COLOR0_CLEAR_WORD3; // = 0x28C98, //
+ GLboolean enabled;
+ GLboolean dirty;
+} EVERGREEN_RENDER_TARGET_STATE;
+
+typedef struct _EVERGREEN_CONFIG
+{
+ union UINT_FLOAT SPI_CONFIG_CNTL; // = 0x9100, // DIFF
+ union UINT_FLOAT SPI_CONFIG_CNTL_1; // = 0x913C, // DIFF
+ union UINT_FLOAT CP_PERFMON_CNTL; // = 0x87FC, // SAME
+ union UINT_FLOAT SQ_MS_FIFO_SIZES; // = 0x8CF0, // SAME
+
+ union UINT_FLOAT SQ_CONFIG; // = 0x8C00, // DIFF
+ union UINT_FLOAT SQ_GPR_RESOURCE_MGMT_1; // = 0x8C04, // SAME
+ union UINT_FLOAT SQ_GPR_RESOURCE_MGMT_2; // = 0x8C08, // SAME
+ union UINT_FLOAT SQ_GPR_RESOURCE_MGMT_3; // = 0x8C0C, //
+
+ union UINT_FLOAT SQ_THREAD_RESOURCE_MGMT; // = 0x8C18, // SAME 0x8C0C
+ union UINT_FLOAT SQ_THREAD_RESOURCE_MGMT_2; // = 0x8C1C, //
+ union UINT_FLOAT SQ_STACK_RESOURCE_MGMT_1; // = 0x8C20, // SAME 0x8C10
+ union UINT_FLOAT SQ_STACK_RESOURCE_MGMT_2; // = 0x8C24, // SAME 0x8C14
+ union UINT_FLOAT SQ_STACK_RESOURCE_MGMT_3; // = 0x8C28, //
+
+ union UINT_FLOAT SQ_DYN_GPR_CNTL_PS_FLUSH_REQ; // = 0x8D8C, // DIFF
+ union UINT_FLOAT SQ_LDS_RESOURCE_MGMT; // = 0x8E2C, //
+ union UINT_FLOAT VGT_CACHE_INVALIDATION; // = 0x88C4, // DIFF
+ union UINT_FLOAT VGT_GS_VERTEX_REUSE; // = 0x88D4, // SAME
+ union UINT_FLOAT PA_SC_FORCE_EOV_MAX_CNTS; // = 0x8B24, // SAME
+ union UINT_FLOAT PA_SC_LINE_STIPPLE_STATE; // = 0x8B10, // SAME
+ union UINT_FLOAT PA_CL_ENHANCE; // = 0x8A14, // SAME
+} EVERGREEN_CONFIG;
+
+typedef struct _EVERGREEN_PS_RES
+{
+ union UINT_FLOAT SQ_PGM_START_PS; //// // = 0x28840, // SAME
+ GLboolean dirty;
+
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_0; // = 0x28940, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_1; // = 0x28944, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_2; // = 0x28948, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_3; // = 0x2894C, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_4; // = 0x28950, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_5; // = 0x28954, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_6; // = 0x28958, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_7; // = 0x2895C, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_8; // = 0x28960, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_9; // = 0x28964, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_10; // = 0x28968, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_11; // = 0x2896C, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_12; // = 0x28970, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_13; // = 0x28974, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_14; // = 0x28978, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_PS_15; // = 0x2897C, // SAME
+
+ int num_consts;
+ union UINT_FLOAT consts[EVERGREEN_MAX_DX9_CONSTS][4];
+} EVERGREEN_PS_RES;
+
+typedef struct _EVERGREEN_VS_RES
+{
+ union UINT_FLOAT SQ_PGM_START_VS; //// // = 0x2885C, // SAME 0x28858
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_VS_0; //// // = 0x28180, //?
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_0; //// // = 0x28980, // SAME
+
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_1; // = 0x28984, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_2; // = 0x28988, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_3; // = 0x2898C, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_4; // = 0x28990, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_5; // = 0x28994, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_6; // = 0x28998, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_7; // = 0x2899C, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_8; // = 0x289A0, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_9; // = 0x289A4, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_10; // = 0x289A8, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_11; // = 0x289AC, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_12; // = 0x289B0, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_13; // = 0x289B4, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_14; // = 0x289B8, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_15; // = 0x289BC, // SAME
+
+ GLboolean dirty;
+ int num_consts;
+ union UINT_FLOAT consts[EVERGREEN_MAX_DX9_CONSTS][4];
+} EVERGREEN_VS_RES;
+
+typedef struct _EVERGREEN_CHIP_CONTEXT
+{
+/* Registers from PA block: */
+ union UINT_FLOAT PA_SC_SCREEN_SCISSOR_TL; //// // = 0x28030, // DIFF
+ union UINT_FLOAT PA_SC_SCREEN_SCISSOR_BR; //// // = 0x28034, // DIFF
+ union UINT_FLOAT PA_SC_WINDOW_OFFSET; //// // = 0x28200, // DIFF
+ union UINT_FLOAT PA_SC_WINDOW_SCISSOR_TL; //// // = 0x28204, // DIFF
+ union UINT_FLOAT PA_SC_WINDOW_SCISSOR_BR; //// // = 0x28208, // DIFF
+ union UINT_FLOAT PA_SC_CLIPRECT_RULE; //// // = 0x2820C, // SAME
+ union UINT_FLOAT PA_SC_CLIPRECT_0_TL; //// // = 0x28210, // DIFF
+ union UINT_FLOAT PA_SC_CLIPRECT_0_BR; //// // = 0x28214, // DIFF
+ union UINT_FLOAT PA_SC_CLIPRECT_1_TL; //// // = 0x28218, // DIFF
+ union UINT_FLOAT PA_SC_CLIPRECT_1_BR; //// // = 0x2821C, // DIFF
+ union UINT_FLOAT PA_SC_CLIPRECT_2_TL; //// // = 0x28220, // DIFF
+ union UINT_FLOAT PA_SC_CLIPRECT_2_BR; //// // = 0x28224, // DIFF
+ union UINT_FLOAT PA_SC_CLIPRECT_3_TL; //// // = 0x28228, // DIFF
+ union UINT_FLOAT PA_SC_CLIPRECT_3_BR; //// // = 0x2822C, // DIFF
+ union UINT_FLOAT PA_SC_EDGERULE; // = 0x28230, // SAME
+ union UINT_FLOAT PA_SU_HARDWARE_SCREEN_OFFSET; // = 0x28234, //
+ union UINT_FLOAT PA_SC_GENERIC_SCISSOR_TL; //// // = 0x28240, // DIFF
+ union UINT_FLOAT PA_SC_GENERIC_SCISSOR_BR; //// // = 0x28244, // DIFF
+
+ EVERGREEN_VIEWPORT_STATE viewport[EVERGREEN_MAX_VIEWPORTS];
+ EVERGREEN_UCP_STATE ucp[EVERGREEN_MAX_UCP];
+
+ union UINT_FLOAT PA_CL_POINT_X_RAD; // = 0x287D4, // SAME 0x28E10
+ union UINT_FLOAT PA_CL_POINT_Y_RAD; // = 0x287D8, // SAME 0x28E14
+ union UINT_FLOAT PA_CL_POINT_SIZE; // = 0x287DC, // SAME 0x28E18
+ union UINT_FLOAT PA_CL_POINT_CULL_RAD; // = 0x287E0, // SAME 0x28E1C
+ union UINT_FLOAT PA_CL_CLIP_CNTL; //// // = 0x28810, // SAME
+ union UINT_FLOAT PA_SU_SC_MODE_CNTL; //// // = 0x28814, // SAME
+ union UINT_FLOAT PA_CL_VTE_CNTL; //// // = 0x28818, // SAME
+ union UINT_FLOAT PA_CL_VS_OUT_CNTL; //// // = 0x2881C, // SAME
+ union UINT_FLOAT PA_CL_NANINF_CNTL; //// // = 0x28820, // SAME
+ union UINT_FLOAT PA_SU_LINE_STIPPLE_CNTL; // = 0x28824, //
+ union UINT_FLOAT PA_SU_LINE_STIPPLE_SCALE; // = 0x28828, //
+ union UINT_FLOAT PA_SU_PRIM_FILTER_CNTL; // = 0x2882C, //
+ union UINT_FLOAT PA_SU_POINT_SIZE; //// // = 0x28A00, // SAME
+ union UINT_FLOAT PA_SU_POINT_MINMAX; //// // = 0x28A04, // SAME
+ union UINT_FLOAT PA_SU_LINE_CNTL; //// // = 0x28A08, // SAME
+ union UINT_FLOAT PA_SC_LINE_STIPPLE; // = 0x28A0C, // SAME
+ union UINT_FLOAT PA_SC_MODE_CNTL_0; //// // = 0x28A48, //
+ union UINT_FLOAT PA_SC_MODE_CNTL_1; //// // = 0x28A4C, //
+ union UINT_FLOAT PA_SU_POLY_OFFSET_DB_FMT_CNTL; //// // = 0x28B78, // SAME 0x28DF8
+ union UINT_FLOAT PA_SU_POLY_OFFSET_CLAMP; //// // = 0x28B7C, // SAME 0x28DFC
+ union UINT_FLOAT PA_SU_POLY_OFFSET_FRONT_SCALE;//// // = 0x28B80, // SAME 0x28E00
+ union UINT_FLOAT PA_SU_POLY_OFFSET_FRONT_OFFSET; //// // = 0x28B84, // SAME 0x28E04
+ union UINT_FLOAT PA_SU_POLY_OFFSET_BACK_SCALE; //// // = 0x28B88, // SAME 0x28E08
+ union UINT_FLOAT PA_SU_POLY_OFFSET_BACK_OFFSET; //// // = 0x28B8C, // SAME 0x28E0C
+ union UINT_FLOAT PA_SC_LINE_CNTL; //// // = 0x28C00, // DIFF
+ union UINT_FLOAT PA_SC_AA_CONFIG; //// // = 0x28C04, // SAME
+ union UINT_FLOAT PA_SU_VTX_CNTL; //// // = 0x28C08, // SAME
+ union UINT_FLOAT PA_CL_GB_VERT_CLIP_ADJ; //// // = 0x28C0C, // SAME
+ union UINT_FLOAT PA_CL_GB_VERT_DISC_ADJ; //// // = 0x28C10, // SAME
+ union UINT_FLOAT PA_CL_GB_HORZ_CLIP_ADJ; //// // = 0x28C14, // SAME
+ union UINT_FLOAT PA_CL_GB_HORZ_DISC_ADJ; //// // = 0x28C18, // SAME
+ union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_0; //// // = 0x28C1C, //
+ union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_1; //// // = 0x28C20, //
+ union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_2; //// // = 0x28C24, //
+ union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_3; //// // = 0x28C28, //
+ union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_4; //// // = 0x28C2C, //
+ union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_5; //// // = 0x28C30, //
+ union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_6; //// // = 0x28C34, //
+ union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_7; //// // = 0x28C38, //
+ union UINT_FLOAT PA_SC_AA_MASK; //// // = 0x28C3C, // SAME 0x28C48
+
+/* Registers from VGT block: */
+ union UINT_FLOAT VGT_INDEX_TYPE; // = 0x895C, // SAME
+ union UINT_FLOAT VGT_PRIMITIVE_TYPE; // = 0x8958, // SAME
+ union UINT_FLOAT VGT_MAX_VTX_INDX; //// // = 0x28400, // SAME
+ union UINT_FLOAT VGT_MIN_VTX_INDX; //// // = 0x28404, // SAME
+ union UINT_FLOAT VGT_INDX_OFFSET; //// // = 0x28408, // SAME
+ union UINT_FLOAT VGT_MULTI_PRIM_IB_RESET_INDX; // = 0x2840C, // SAME
+
+ union UINT_FLOAT VGT_DRAW_INITIATOR; // = 0x287F0, // SAME
+ union UINT_FLOAT VGT_IMMED_DATA; // = 0x287F4, // SAME
+
+ union UINT_FLOAT VGT_OUTPUT_PATH_CNTL; //// // = 0x28A10, // DIFF
+ union UINT_FLOAT VGT_HOS_CNTL; // = 0x28A14, // SAME
+ union UINT_FLOAT VGT_HOS_MAX_TESS_LEVEL; // = 0x28A18, // SAME
+ union UINT_FLOAT VGT_HOS_MIN_TESS_LEVEL; // = 0x28A1C, // SAME
+ union UINT_FLOAT VGT_HOS_REUSE_DEPTH; // = 0x28A20, // SAME
+ union UINT_FLOAT VGT_GROUP_PRIM_TYPE; // = 0x28A24, // SAME
+ union UINT_FLOAT VGT_GROUP_FIRST_DECR; // = 0x28A28, // SAME
+ union UINT_FLOAT VGT_GROUP_DECR; // = 0x28A2C, // SAME
+ union UINT_FLOAT VGT_GROUP_VECT_0_CNTL; // = 0x28A30, // SAME
+ union UINT_FLOAT VGT_GROUP_VECT_1_CNTL; // = 0x28A34, // SAME
+ union UINT_FLOAT VGT_GROUP_VECT_0_FMT_CNTL; // = 0x28A38, // SAME
+ union UINT_FLOAT VGT_GROUP_VECT_1_FMT_CNTL; // = 0x28A3C, // SAME
+ union UINT_FLOAT VGT_GS_MODE; //// // = 0x28A40, // DIFF
+
+ union UINT_FLOAT VGT_PRIMITIVEID_EN; //// // = 0x28A84, // SAME
+ union UINT_FLOAT VGT_DMA_NUM_INSTANCES; //// // = 0x28A88, // SAME
+ union UINT_FLOAT VGT_EVENT_INITIATOR; // = 0x28A90, // SAME
+ union UINT_FLOAT VGT_MULTI_PRIM_IB_RESET_EN; // = 0x28A94, // SAME
+ union UINT_FLOAT VGT_INSTANCE_STEP_RATE_0; //// // = 0x28AA0, // SAME
+ union UINT_FLOAT VGT_INSTANCE_STEP_RATE_1; //// // = 0x28AA4, // SAME
+ union UINT_FLOAT VGT_REUSE_OFF; //// // = 0x28AB4, // SAME
+ union UINT_FLOAT VGT_VTX_CNT_EN; //// // = 0x28AB8, // SAME
+
+ union UINT_FLOAT VGT_SHADER_STAGES_EN; //// // = 0x28B54, //
+
+ union UINT_FLOAT VGT_STRMOUT_CONFIG; //// // = 0x28B94, //
+ union UINT_FLOAT VGT_STRMOUT_BUFFER_CONFIG; //// // = 0x28B98, //
+ union UINT_FLOAT VGT_VERTEX_REUSE_BLOCK_CNTL;//// // = 0x28C58, // SAME
+ union UINT_FLOAT VGT_OUT_DEALLOC_CNTL; //// // = 0x28C5C, // SAME
+
+/* Registers from SQ block: */
+ union UINT_FLOAT SQ_VTX_SEMANTIC_0; //// // = 0x28380, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_1; //// // = 0x28384, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_2; //// // = 0x28388, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_3; //// // = 0x2838C, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_4; //// // = 0x28390, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_5; //// // = 0x28394, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_6; //// // = 0x28398, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_7; //// // = 0x2839C, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_8; //// // = 0x283A0, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_9; //// // = 0x283A4, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_10; //// // = 0x283A8, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_11; //// // = 0x283AC, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_12; //// // = 0x283B0, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_13; //// // = 0x283B4, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_14; //// // = 0x283B8, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_15; //// // = 0x283BC, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_16; //// // = 0x283C0, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_17; //// // = 0x283C4, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_18; //// // = 0x283C8, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_19; //// // = 0x283CC, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_20; //// // = 0x283D0, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_21; //// // = 0x283D4, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_22; //// // = 0x283D8, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_23; //// // = 0x283DC, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_24; //// // = 0x283E0, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_25; //// // = 0x283E4, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_26; //// // = 0x283E8, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_27; //// // = 0x283EC, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_28; //// // = 0x283F0, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_29; //// // = 0x283F4, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_30; //// // = 0x283F8, // SAME
+ union UINT_FLOAT SQ_VTX_SEMANTIC_31; //// // = 0x283FC, // SAME
+ union UINT_FLOAT SQ_DYN_GPR_RESOURCE_LIMIT_1;//// // = 0x28838, //
+
+ union UINT_FLOAT SQ_PGM_RESOURCES_PS; //// // = 0x28844, // DIFF 0x28850
+ union UINT_FLOAT SQ_PGM_RESOURCES_2_PS; //// // = 0x28848, //
+ union UINT_FLOAT SQ_PGM_EXPORTS_PS; //// // = 0x2884C, // SAME 0x28854
+
+ union UINT_FLOAT SQ_PGM_RESOURCES_VS;//// // = 0x28860, // DIFF 0x28868
+ union UINT_FLOAT SQ_PGM_RESOURCES_2_VS; //// // = 0x28864, //
+ union UINT_FLOAT SQ_PGM_START_GS; //// // = 0x28874, // SAME 0x2886C
+ union UINT_FLOAT SQ_PGM_RESOURCES_GS; //// // = 0x28878, // DIFF 0x2887C
+ union UINT_FLOAT SQ_PGM_RESOURCES_2_GS; //// // = 0x2887C, //
+ union UINT_FLOAT SQ_PGM_START_ES; //// // = 0x2888C, // SAME 0x28880
+ union UINT_FLOAT SQ_PGM_RESOURCES_ES; //// // = 0x28890, // DIFF
+ union UINT_FLOAT SQ_PGM_RESOURCES_2_ES; //// // = 0x28894, //
+ union UINT_FLOAT SQ_PGM_START_FS; //// // = 0x288A4, // SAME 0x28894
+ union UINT_FLOAT SQ_PGM_RESOURCES_FS; //// // = 0x288A8, // DIFF 0x288A4
+ union UINT_FLOAT SQ_PGM_START_HS; // = 0x288B8, //
+ union UINT_FLOAT SQ_PGM_RESOURCES_HS; // = 0x288BC, //
+ union UINT_FLOAT SQ_PGM_RESOURCES_2_HS;//// // = 0x288C0, //
+ union UINT_FLOAT SQ_PGM_START_LS; // = 0x288D0, //
+ union UINT_FLOAT SQ_PGM_RESOURCES_LS; // = 0x288D4, //
+ union UINT_FLOAT SQ_PGM_RESOURCES_2_LS; //// // = 0x288D8, //
+ union UINT_FLOAT SQ_LDS_ALLOC_PS; //// // = 0x288EC, //
+ union UINT_FLOAT SQ_ESGS_RING_ITEMSIZE; //// // = 0x28900, // SAME 0x288A8
+ union UINT_FLOAT SQ_GSVS_RING_ITEMSIZE; //// // = 0x28904, // SAME 0x288AC
+ union UINT_FLOAT SQ_ESTMP_RING_ITEMSIZE; //// // = 0x28908, // SAME 0x288B0
+ union UINT_FLOAT SQ_GSTMP_RING_ITEMSIZE; //// // = 0x2890C, // SAME 0x288B4
+ union UINT_FLOAT SQ_VSTMP_RING_ITEMSIZE; //// // = 0x28910, // SAME 0x288B8
+ union UINT_FLOAT SQ_PSTMP_RING_ITEMSIZE; //// // = 0x28914, // SAME 0x288BC
+ union UINT_FLOAT SQ_GS_VERT_ITEMSIZE; //// // = 0x2891C, // SAME 0x288C8
+ union UINT_FLOAT SQ_GS_VERT_ITEMSIZE_1; // = 0x28920, //
+ union UINT_FLOAT SQ_GS_VERT_ITEMSIZE_2; // = 0x28924, //
+ union UINT_FLOAT SQ_GS_VERT_ITEMSIZE_3; // = 0x28928, //
+
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_0; // = 0x289C0, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_1; // = 0x289C4, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_2; // = 0x289C8, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_3; // = 0x289CC, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_4; // = 0x289D0, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_5; // = 0x289D4, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_6; // = 0x289D8, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_7; // = 0x289DC, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_8; // = 0x289E0, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_9; // = 0x289E4, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_10; // = 0x289E8, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_11; // = 0x289EC, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_12; // = 0x289F0, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_13; // = 0x289F4, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_14; // = 0x289F8, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_GS_15; // = 0x289FC, // SAME
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_0; // = 0x28F00, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_1; // = 0x28F04, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_2; // = 0x28F08, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_3; // = 0x28F0C, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_4; // = 0x28F10, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_5; // = 0x28F14, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_6; // = 0x28F18, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_7; // = 0x28F1C, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_8; // = 0x28F20, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_9; // = 0x28F24, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_10; // = 0x28F28, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_11; // = 0x28F2C, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_12; // = 0x28F30, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_13; // = 0x28F34, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_14; // = 0x28F38, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_HS_15; // = 0x28F3C, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_0; // = 0x28F40, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_1; // = 0x28F44, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_2; // = 0x28F48, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_3; // = 0x28F4C, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_4; // = 0x28F50, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_5; // = 0x28F54, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_6; // = 0x28F58, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_7; // = 0x28F5C, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_8; // = 0x28F60, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_9; // = 0x28F64, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_10; // = 0x28F68, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_11; // = 0x28F6C, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_12; // = 0x28F70, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_13; // = 0x28F74, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_14; // = 0x28F78, //
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_LS_15; // = 0x28F7C, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_0; // = 0x28F80, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_1; // = 0x28F84, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_2; // = 0x28F88, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_3; // = 0x28F8C, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_4; // = 0x28F90, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_5; // = 0x28F94, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_6; // = 0x28F98, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_7; // = 0x28F9C, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_8; // = 0x28FA0, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_9; // = 0x28FA4, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_10; // = 0x28FA8, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_11; // = 0x28FAC, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_12; // = 0x28FB0, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_13; // = 0x28FB4, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_14; // = 0x28FB8, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_HS_15; // = 0x28FBC, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_0; // = 0x28FC0, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_1; // = 0x28FC4, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_2; // = 0x28FC8, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_3; // = 0x28FCC, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_4; // = 0x28FD0, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_5; // = 0x28FD4, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_6; // = 0x28FD8, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_7; // = 0x28FDC, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_8; // = 0x28FE0, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_9; // = 0x28FE4, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_10; // = 0x28FE8, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_11; // = 0x28FEC, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_12; // = 0x28FF0, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_13; // = 0x28FF4, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_14; // = 0x28FF8, //
+ union UINT_FLOAT SQ_ALU_CONST_BUFFER_SIZE_LS_15; // = 0x28FFC, //
+
+ EVERGREEN_PS_RES ps;
+ EVERGREEN_VS_RES vs;
+
+/* Registers from SPI block: */
+ union UINT_FLOAT SPI_VS_OUT_ID_0; //// // = 0x2861C, // SAME 0x28614
+ union UINT_FLOAT SPI_VS_OUT_ID_1; //// // = 0x28620, // SAME 0x28618
+ union UINT_FLOAT SPI_VS_OUT_ID_2; //// // = 0x28624, // SAME 0x2861C
+ union UINT_FLOAT SPI_VS_OUT_ID_3; //// // = 0x28628, // SAME 0x28620
+ union UINT_FLOAT SPI_VS_OUT_ID_4; //// // = 0x2862C, // SAME 0x28624
+ union UINT_FLOAT SPI_VS_OUT_ID_5; //// // = 0x28630, // SAME 0x28628
+ union UINT_FLOAT SPI_VS_OUT_ID_6; //// // = 0x28634, // SAME 0x2862C
+ union UINT_FLOAT SPI_VS_OUT_ID_7; //// // = 0x28638, // SAME 0x28630
+ union UINT_FLOAT SPI_VS_OUT_ID_8; //// // = 0x2863C, // SAME 0x28634
+ union UINT_FLOAT SPI_VS_OUT_ID_9; //// // = 0x28640, // SAME 0x28638
+ union UINT_FLOAT SPI_PS_INPUT_CNTL[32]; //// // = 0x28644, // SAME
+
+ union UINT_FLOAT SPI_VS_OUT_CONFIG; //// // = 0x286C4, // SAME
+ union UINT_FLOAT SPI_THREAD_GROUPING; //// // = 0x286C8, // DIFF
+ union UINT_FLOAT SPI_PS_IN_CONTROL_0; //// // = 0x286CC, // SAME
+ union UINT_FLOAT SPI_PS_IN_CONTROL_1; //// // = 0x286D0, // SAME
+ union UINT_FLOAT SPI_INTERP_CONTROL_0; //// // = 0x286D4, // SAME
+ union UINT_FLOAT SPI_INPUT_Z; //// // = 0x286D8, // SAME
+ union UINT_FLOAT SPI_FOG_CNTL; //// // = 0x286DC, // SAME
+ union UINT_FLOAT SPI_BARYC_CNTL; //// // = 0x286E0, //
+ union UINT_FLOAT SPI_PS_IN_CONTROL_2; //// // = 0x286E4, //
+ union UINT_FLOAT SPI_COMPUTE_INPUT_CNTL; // = 0x286E8, //
+ union UINT_FLOAT SPI_COMPUTE_NUM_THREAD_X; // = 0x286EC, //
+ union UINT_FLOAT SPI_COMPUTE_NUM_THREAD_Y; // = 0x286F0, //
+ union UINT_FLOAT SPI_COMPUTE_NUM_THREAD_Z; // = 0x286F4, //
+
+/* Registers from SX block: */
+ union UINT_FLOAT SX_MISC; // = 0x28350, // SAME
+ union UINT_FLOAT SX_SURFACE_SYNC; // = 0x28354, // DIFF
+ union UINT_FLOAT SX_ALPHA_TEST_CONTROL; //// // = 0x28410, // SAME
+ union UINT_FLOAT SX_ALPHA_REF; // = 0x28438, // SAME
+
+/* Registers from DB block: */
+ union UINT_FLOAT DB_RENDER_CONTROL; //// // = 0x28000, // DIFF 0x28D0C
+ union UINT_FLOAT DB_COUNT_CONTROL; //// // = 0x28004, //
+ union UINT_FLOAT DB_DEPTH_VIEW; //// // = 0x28008, // DIFF 0x28004
+ union UINT_FLOAT DB_RENDER_OVERRIDE; //// // = 0x2800C, // DIFF 0x28D10
+ union UINT_FLOAT DB_RENDER_OVERRIDE2; //// // = 0x28010, //
+ union UINT_FLOAT DB_HTILE_DATA_BASE; //// // = 0x28014, // SAME
+ union UINT_FLOAT DB_STENCIL_CLEAR; //// // = 0x28028, // SAME
+ union UINT_FLOAT DB_DEPTH_CLEAR; //// // = 0x2802C, // SAME
+ union UINT_FLOAT DB_Z_INFO; //// // = 0x28040, //
+ union UINT_FLOAT DB_STENCIL_INFO; //// // = 0x28044, //
+ union UINT_FLOAT DB_Z_READ_BASE; //// // = 0x28048, //
+ union UINT_FLOAT DB_STENCIL_READ_BASE;//// // = 0x2804C, //
+ union UINT_FLOAT DB_Z_WRITE_BASE; //// // = 0x28050, //
+ union UINT_FLOAT DB_STENCIL_WRITE_BASE; //// // = 0x28054, //
+ union UINT_FLOAT DB_DEPTH_SIZE; //// // = 0x28058, // DIFF 0x28000
+ union UINT_FLOAT DB_DEPTH_SLICE; //// // = 0x2805C, //
+ union UINT_FLOAT DB_STENCILREFMASK; // = 0x28430, // SAME
+ union UINT_FLOAT DB_STENCILREFMASK_BF; // = 0x28434, // SAME
+ union UINT_FLOAT DB_DEPTH_CONTROL; //// // = 0x28800, // SAME
+ union UINT_FLOAT DB_SHADER_CONTROL;//// // = 0x2880C, // DIFF
+ union UINT_FLOAT DB_HTILE_SURFACE; //// // = 0x28ABC, // SAME 0x28D24
+ union UINT_FLOAT DB_SRESULTS_COMPARE_STATE0; //// // = 0x28AC0, // SAME 0x28D28
+ union UINT_FLOAT DB_SRESULTS_COMPARE_STATE1; //// // = 0x28AC4, // SAME 0x28D2C
+ union UINT_FLOAT DB_PRELOAD_CONTROL; //// // = 0x28AC8, // SAME 0x28D30
+ union UINT_FLOAT DB_ALPHA_TO_MASK; //// // = 0x28B70, // SAME 0x28D44
+
+/* Registers from CB block: */
+ union UINT_FLOAT CB_TARGET_MASK; //// // = 0x28238, // SAME
+ union UINT_FLOAT CB_SHADER_MASK; //// // = 0x2823C, // SAME
+ union UINT_FLOAT CB_BLEND_RED; //// // = 0x28414, // SAME
+ union UINT_FLOAT CB_BLEND_GREEN; //// // = 0x28418, // SAME
+ union UINT_FLOAT CB_BLEND_BLUE; //// // = 0x2841C, // SAME
+ union UINT_FLOAT CB_BLEND_ALPHA; //// // = 0x28420, // SAME
+ union UINT_FLOAT CB_BLEND0_CONTROL; //// // = 0x28780, // DIFF
+ union UINT_FLOAT CB_BLEND1_CONTROL; // = 0x28784, // DIFF
+ union UINT_FLOAT CB_BLEND2_CONTROL; // = 0x28788, // DIFF
+ union UINT_FLOAT CB_BLEND3_CONTROL; // = 0x2878C, // DIFF
+ union UINT_FLOAT CB_BLEND4_CONTROL; // = 0x28790, // DIFF
+ union UINT_FLOAT CB_BLEND5_CONTROL; // = 0x28794, // DIFF
+ union UINT_FLOAT CB_BLEND6_CONTROL; // = 0x28798, // DIFF
+ union UINT_FLOAT CB_BLEND7_CONTROL; // = 0x2879C, // DIFF
+ union UINT_FLOAT CB_COLOR_CONTROL; //// // = 0x28808, // DIFF
+ union UINT_FLOAT CB_CLRCMP_CONTROL; //// // = 0x28C40, // SAME 0x28C30
+ union UINT_FLOAT CB_CLRCMP_SRC; //// // = 0x28C44, // SAME 0x28C34
+ union UINT_FLOAT CB_CLRCMP_DST; //// // = 0x28C48, // SAME 0x28C38
+ union UINT_FLOAT CB_CLRCMP_MSK; //// // = 0x28C4C, // SAME 0x28C3C
+
+ EVERGREEN_RENDER_TARGET_STATE render_target[EVERGREEN_MAX_RENDER_TARGETS];
+
+ radeonTexObj* textures[R700_TEXTURE_NUMBERUNITS];
+
+ EVERGREEN_CONFIG evergreen_config;
+
+ GLboolean bEnablePerspective;
+
+} EVERGREEN_CHIP_CONTEXT;
+
+#endif /* _EVERGREEN_CHIP_H_ */ \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/evergreen_context.c b/src/mesa/drivers/dri/r600/evergreen_context.c
new file mode 100644
index 00000000000..65b5898efa6
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_context.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#include "main/glheader.h"
+#include "main/api_arrayelt.h"
+#include "main/context.h"
+#include "main/simple_list.h"
+#include "main/imports.h"
+#include "main/bufferobj.h"
+#include "main/texobj.h"
+
+#include "radeon_common_context.h"
+#include "evergreen_context.h"
+#include "evergreen_state.h"
+#include "r600_blit.h"
+
+static void evergreen_get_lock(radeonContextPtr rmesa)
+{
+ drm_radeon_sarea_t *sarea = rmesa->sarea;
+
+ if (sarea->ctx_owner != rmesa->dri.hwContext) {
+ sarea->ctx_owner = rmesa->dri.hwContext;
+ if (!rmesa->radeonScreen->kernel_mm)
+ radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom);
+ }
+}
+
+static void evergreen_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa)
+{
+ /* please flush pipe do all pending work */
+ /* to be enabled */
+}
+
+static void evergreen_vtbl_pre_emit_atoms(radeonContextPtr radeon)
+{
+ //TODO apr.01
+ //r700Start3D((context_t *)radeon);
+}
+
+static void evergreen_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ if (mode)
+ context->radeon.Fallback |= bit;
+ else
+ context->radeon.Fallback &= ~bit;
+}
+
+static void evergreen_emit_query_finish(radeonContextPtr radeon)
+{
+ //TODO apr.01
+ //context_t *context = (context_t*) radeon;
+ //BATCH_LOCALS(&context->radeon);
+
+ struct radeon_query_object *query = radeon->query.current;
+
+ //BEGIN_BATCH_NO_AUTOSTATE(4 + 2);
+ //R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE, 2));
+ //R600_OUT_BATCH(ZPASS_DONE);
+ //R600_OUT_BATCH(query->curr_offset + 8); /* hw writes qwords */
+ //R600_OUT_BATCH(0x00000000);
+ //R600_OUT_BATCH_RELOC(VGT_EVENT_INITIATOR, query->bo, 0, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ //END_BATCH();
+ //assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
+
+void evergreen_init_vtbl(radeonContextPtr radeon)
+{
+ radeon->vtbl.get_lock = evergreen_get_lock;
+ radeon->vtbl.update_viewport_offset = evergreenUpdateViewportOffset;
+ radeon->vtbl.emit_cs_header = evergreen_vtbl_emit_cs_header;
+ radeon->vtbl.swtcl_flush = NULL;
+ radeon->vtbl.pre_emit_atoms = evergreen_vtbl_pre_emit_atoms;
+ radeon->vtbl.fallback = evergreen_fallback;
+ radeon->vtbl.emit_query_finish = evergreen_emit_query_finish;
+ radeon->vtbl.check_blit = r600_check_blit;
+ radeon->vtbl.blit = r600_blit;
+ radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
+}
+
+
+
diff --git a/src/mesa/slang/slang_link.h b/src/mesa/drivers/dri/r600/evergreen_context.h
index 3e9fa2d743d..4e50999c98f 100644
--- a/src/mesa/slang/slang_link.h
+++ b/src/mesa/drivers/dri/r600/evergreen_context.h
@@ -1,8 +1,5 @@
/*
- * Mesa 3-D graphics library
- * Version: 7.2
- *
- * Copyright (C) 2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -17,21 +14,25 @@
* 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
+ * THE COPYRIGHT HOLDER(S) 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 SLANG_LINK_H
-#define SLANG_LINK_H 1
+/*
+ * Authors:
+ */
+
+#ifndef _EVERGREEN_CONTEXT_H_
+#define _EVERGREEN_CONTEXT_H_
+
+extern void evergreen_init_vtbl(radeonContextPtr radeon);
+
+#endif //_EVERGREEN_CONTEXT_H_
-#include "main/mtypes.h"
-extern void
-_slang_link(GLcontext *ctx, GLhandleARB h,
- struct gl_shader_program *shProg);
-#endif
diff --git a/src/mesa/drivers/dri/r600/evergreen_diff.h b/src/mesa/drivers/dri/r600/evergreen_diff.h
new file mode 100644
index 00000000000..c3a5fd0a38a
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_diff.h
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#ifndef _EVERGREEN_DIFF_H_
+#define _EVERGREEN_DIFF_H_
+
+enum {
+ /* CB_BLEND_CONTROL */
+ EG_CB_BLENDX_CONTROL_ENABLE_bit = 1 << 30,
+ /* PA_SC_SCREEN_SCISSOR_TL */
+ EG_PA_SC_SCREEN_SCISSOR_TL__TL_X_mask = 0xffff << 0,
+ EG_PA_SC_SCREEN_SCISSOR_TL__TL_Y_mask = 0xffff << 16,
+ /* PA_SC_SCREEN_SCISSOR_BR */
+ EG_PA_SC_SCREEN_SCISSOR_BR__BR_X_mask = 0xffff << 0,
+ EG_PA_SC_SCREEN_SCISSOR_BR__BR_Y_mask = 0xffff << 16,
+ /* PA_SC_WINDOW_SCISSOR_TL */
+ EG_PA_SC_WINDOW_SCISSOR_TL__TL_X_mask = 0x7fff << 0,
+ EG_PA_SC_WINDOW_SCISSOR_TL__TL_Y_mask = 0x7fff << 16,
+ /* PA_SC_WINDOW_SCISSOR_BR */
+ EG_PA_SC_WINDOW_SCISSOR_BR__BR_X_mask = 0x7fff << 0,
+ EG_PA_SC_WINDOW_SCISSOR_BR__BR_Y_mask = 0x7fff << 16,
+ /* PA_SC_CLIPRECT_0_TL */
+ EG_PA_SC_CLIPRECT_0_TL__TL_X_mask = 0x7fff << 0,
+ EG_PA_SC_CLIPRECT_0_TL__TL_Y_mask = 0x7fff << 16,
+ /* PA_SC_CLIPRECT_0_BR */
+ EG_PA_SC_CLIPRECT_0_BR__BR_X_mask = 0x7fff << 0,
+ EG_PA_SC_CLIPRECT_0_BR__BR_Y_mask = 0x7fff << 16,
+ /* PA_SC_GENERIC_SCISSOR_TL */
+ EG_PA_SC_GENERIC_SCISSOR_TL__TL_X_mask = 0x7fff << 0,
+ EG_PA_SC_GENERIC_SCISSOR_TL__TL_Y_mask = 0x7fff << 16,
+ /* PA_SC_GENERIC_SCISSOR_BR */
+ EG_PA_SC_GENERIC_SCISSOR_BR__BR_X_mask = 0x7fff << 0,
+ EG_PA_SC_GENERIC_SCISSOR_BR__BR_Y_mask = 0x7fff << 16,
+ /* PA_SC_VPORT_SCISSOR_0_TL */
+ EG_PA_SC_VPORT_SCISSOR_0_TL__TL_X_mask = 0x7fff << 0,
+ EG_PA_SC_VPORT_SCISSOR_0_TL__TL_Y_mask = 0x7fff << 16,
+ /* PA_SC_VPORT_SCISSOR_0_BR */
+ EG_PA_SC_VPORT_SCISSOR_0_BR__BR_X_mask = 0x7fff << 0,
+ EG_PA_SC_VPORT_SCISSOR_0_BR__BR_Y_mask = 0x7fff << 16,
+ /* PA_SC_WINDOW_OFFSET */
+ EG_PA_SC_WINDOW_OFFSET__WINDOW_X_OFFSET_shift = 0,
+ EG_PA_SC_WINDOW_OFFSET__WINDOW_X_OFFSET_mask = 0xffff << 0,
+ EG_PA_SC_WINDOW_OFFSET__WINDOW_Y_OFFSET_shift = 16,
+ EG_PA_SC_WINDOW_OFFSET__WINDOW_Y_OFFSET_mask = 0xffff << 16,
+ /* SPI_BARYC_CNTL */
+ EG_SPI_BARYC_CNTL__PERSP_CENTROID_ENA_shift = 4,
+ EG_SPI_BARYC_CNTL__PERSP_CENTROID_ENA_mask = 0x3 << 4,
+ EG_SPI_BARYC_CNTL__LINEAR_CENTROID_ENA_shift = 20,
+ EG_SPI_BARYC_CNTL__LINEAR_CENTROID_ENA_mask = 0x3 << 20,
+ /* DB_SHADER_CONTROL */
+ EG_DB_SHADER_CONTROL__DUAL_EXPORT_ENABLE_bit = 1 << 9,
+
+ /* DB_Z_INFO */
+ EG_DB_Z_INFO__FORMAT_shift = 0, //2;
+ EG_DB_Z_INFO__FORMAT_mask = 0x3,
+ //2;
+ EG_DB_Z_INFO__ARRAY_MODE_shift = 4, //4;
+ EG_DB_Z_INFO__ARRAY_MODE_mask = 0xf << 4,
+ EG_DB_Z_INFO__TILE_SPLIT_shift = 8, //3;
+ EG_DB_Z_INFO__TILE_SPLIT_mask = 0x7 << 8,
+ //1;
+ EG_DB_Z_INFO__NUM_BANKS_shift = 12, //2;
+ EG_DB_Z_INFO__NUM_BANKS_mask = 0x3 << 12,
+ //2;
+ EG_DB_Z_INFO__BANK_WIDTH_shift = 16, //2;
+ EG_DB_Z_INFO__BANK_WIDTH_mask = 0x3 << 16,
+ //2;
+ EG_DB_Z_INFO__BANK_HEIGHT_shift = 20, //2;
+ EG_DB_Z_INFO__BANK_HEIGHT_mask = 0x3 << 20,
+
+ EG_Z_INVALID = 0x00000000,
+ EG_Z_16 = 0x00000001,
+ EG_Z_24 = 0x00000002,
+ EG_Z_32_FLOAT = 0x00000003,
+ EG_ADDR_SURF_TILE_SPLIT_256B = 0x00000002,
+ EG_ADDR_SURF_8_BANK = 0x00000002,
+ EG_ADDR_SURF_BANK_WIDTH_1 = 0x00000000,
+ EG_ADDR_SURF_BANK_HEIGHT_1 = 0x00000000,
+ /* DB_STENCIL_INFO */
+ EG_DB_STENCIL_INFO__FORMAT_bit = 1, //1;
+ //7;
+ EG_DB_STENCIL_INFO__TILE_SPLIT_shift = 8, //3;
+ EG_DB_STENCIL_INFO__TILE_SPLIT_mask = 0x7 << 8,
+
+ /* DB_DEPTH_SIZE */
+ EG_DB_DEPTH_SIZE__PITCH_TILE_MAX_shift = 0, // 11;
+ EG_DB_DEPTH_SIZE__PITCH_TILE_MAX_mask = 0x7ff,
+ EG_DB_DEPTH_SIZE__HEIGHT_TILE_MAX_shift = 11, // 11;
+ EG_DB_DEPTH_SIZE__HEIGHT_TILE_MAX_mask = 0x7ff << 11,
+
+ /* DB_COUNT_CONTROL */
+ EG_DB_COUNT_CONTROL__ZPASS_INCREMENT_DISABLE_shift = 0, //1
+ EG_DB_COUNT_CONTROL__ZPASS_INCREMENT_DISABLE_bit = 1,
+ EG_DB_COUNT_CONTROL__PERFECT_ZPASS_COUNTS_shift = 1, //1
+ EG_DB_COUNT_CONTROL__PERFECT_ZPASS_COUNTS_bit = 1 << 1,
+
+ /* CB_COLOR_CONTROL */
+ //3;
+ EG_CB_COLOR_CONTROL__DEGAMMA_ENABLE_bit = 1 << 3,//1;
+ EG_CB_COLOR_CONTROL__MODE_shift = 4, //3;
+ EG_CB_COLOR_CONTROL__MODE_mask = 0x7 << 4,
+ //9;
+ EG_CB_COLOR_CONTROL__ROP3_shift = 16, //8;
+ EG_CB_COLOR_CONTROL__ROP3_mask = 0xff << 16,
+ EG_CB_NORMAL = 0x00000001,
+
+ /* CB_COLOR0_INFO */
+ EG_CB_COLOR0_INFO__ENDIAN_shift = 0, //2;
+ EG_CB_COLOR0_INFO__ENDIAN_mask = 0x3,
+ EG_CB_COLOR0_INFO__FORMAT_shift = 2, //6;
+ EG_CB_COLOR0_INFO__FORMAT_mask = 0x3f << 2,
+ EG_CB_COLOR0_INFO__ARRAY_MODE_shift = 8, //4;
+ EG_CB_COLOR0_INFO__ARRAY_MODE_mask = 0xf << 8,
+ EG_CB_COLOR0_INFO__NUMBER_TYPE_shift = 12, //3;
+ EG_CB_COLOR0_INFO__NUMBER_TYPE_mask = 0x7 << 12,
+ EG_CB_COLOR0_INFO__COMP_SWAP_shift = 15, //2;
+ EG_CB_COLOR0_INFO__COMP_SWAP_mask = 0x3 << 15,
+ EG_CB_COLOR0_INFO__FAST_CLEAR_bit = 1 << 17,//1;
+ EG_CB_COLOR0_INFO__COMPRESSION_bit = 1 << 18,//1;
+ EG_CB_COLOR0_INFO__BLEND_CLAMP_bit = 1 << 19,//1;
+ EG_CB_COLOR0_INFO__BLEND_BYPASS_bit = 1 << 20,//1;
+ EG_CB_COLOR0_INFO__SIMPLE_FLOAT_bit = 1 << 21,//1;
+ EG_CB_COLOR0_INFO__ROUND_MODE_bit = 1 << 22,//1;
+ EG_CB_COLOR0_INFO__TILE_COMPACT_bit = 1 << 23,//1;
+ EG_CB_COLOR0_INFO__SOURCE_FORMAT_shift = 24, //2;
+ EG_CB_COLOR0_INFO__SOURCE_FORMAT_mask = 0x3 << 24,
+ EG_CB_COLOR0_INFO__RAT_bit = 1 << 26,//1;
+ EG_CB_COLOR0_INFO__RESOURCE_TYPE_shift = 27, //3;
+ EG_CB_COLOR0_INFO__RESOURCE_TYPE_mask = 0x7 << 27,
+
+ /* CB_COLOR0_ATTRIB */
+ EG_CB_COLOR0_ATTRIB__NON_DISP_TILING_ORDER_shift = 4,
+ EG_CB_COLOR0_ATTRIB__NON_DISP_TILING_ORDER_bit = 1 << 4,
+
+ /* SPI_CONFIG_CNTL_1 */
+ EG_SPI_CONFIG_CNTL_1__VTX_DONE_DELAY_shift = 0,
+ EG_SPI_CONFIG_CNTL_1__VTX_DONE_DELAY_mask = 0xf,
+ /* SQ_MS_FIFO_SIZES */
+ EG_SQ_MS_FIFO_SIZES__CACHE_FIFO_SIZE_shift = 0,
+ EG_SQ_MS_FIFO_SIZES__CACHE_FIFO_SIZE_mask = 0xff,
+ EG_SQ_MS_FIFO_SIZES__FETCH_FIFO_HIWATER_shift = 8,
+ EG_SQ_MS_FIFO_SIZES__FETCH_FIFO_HIWATER_mask = 0x1f << 8,
+ EG_SQ_MS_FIFO_SIZES__DONE_FIFO_HIWATER_shift = 16,
+ EG_SQ_MS_FIFO_SIZES__DONE_FIFO_HIWATER_mask = 0xff << 16,
+ EG_SQ_MS_FIFO_SIZES__ALU_UPDATE_FIFO_HIWATER_shift = 24,
+ EG_SQ_MS_FIFO_SIZES__ALU_UPDATE_FIFO_HIWATER_mask = 0x1f << 24,
+ /* SQ_CONFIG */
+ EG_SQ_CONFIG__VC_ENABLE_bit = 1,
+ EG_SQ_CONFIG__EXPORT_SRC_C_bit = 1 << 1,
+ EG_SQ_CONFIG__PS_PRIO_shift = 24,
+ EG_SQ_CONFIG__PS_PRIO_mask = 0x3 << 24,
+ EG_SQ_CONFIG__VS_PRIO_shift = 26,
+ EG_SQ_CONFIG__VS_PRIO_mask = 0x3 << 26,
+ EG_SQ_CONFIG__GS_PRIO_shift = 28,
+ EG_SQ_CONFIG__GS_PRIO_mask = 0x3 << 28,
+ EG_SQ_CONFIG__ES_PRIO_shift = 30,
+ EG_SQ_CONFIG__ES_PRIO_mask = 0x3 << 30,
+ /* PA_SC_FORCE_EOV_MAX_CNTS */
+ EG_PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_CLK_CNT_shift = 0,
+ EG_PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_CLK_CNT_mask = 0x3fff,
+ EG_PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_REZ_CNT_shift = 16,
+ EG_PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_REZ_CNT_mask = 0x3fff << 16,
+ /* VGT_CACHE_INVALIDATION */
+ EG_VGT_CACHE_INVALIDATION__CACHE_INVALIDATION_shift = 0,
+ EG_VGT_CACHE_INVALIDATION__CACHE_INVALIDATION_mask = 0x3,
+ /* CB_COLOR0_PITCH */
+ EG_CB_COLOR0_PITCH__TILE_MAX_shift = 0,
+ EG_CB_COLOR0_PITCH__TILE_MAX_mask = 0x7ff,
+ /* CB_COLOR0_SLICE */
+ EG_CB_COLOR0_SLICE__TILE_MAX_shift = 0,
+ EG_CB_COLOR0_SLICE__TILE_MAX_mask = 0x3fffff,
+ /* SQ_VTX_CONSTANT_WORD3_0 */
+ EG_SQ_VTX_CONSTANT_WORD3_0__UNCACHED_shift = 2,
+ EG_SQ_VTX_CONSTANT_WORD3_0__UNCACHED_bit = 1 << 2,
+
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_X_shift = 3,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_X_mask = 0x7 << 3,
+
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_Y_shift = 6,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_Y_mask = 0x7 << 6,
+
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_Z_shift = 9,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_Z_mask = 0x7 << 9,
+
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_W_shift = 12,
+ EG_SQ_VTX_CONSTANT_WORD3_0__DST_SEL_W_mask = 0x7 << 12,
+ /* SQ_VTX_CONSTANT_WORD4_0 */
+ EG_SQ_VTX_CONSTANT_WORD4_0__NUM_ELEMENTS_shift = 0,
+ EG_SQ_VTX_CONSTANT_WORD4_0__NUM_ELEMENTS_mask = 0xFFFFFFFF,
+ /* SQ_VTX_CONSTANT_WORD7_0 */
+ EG_SQ_VTX_CONSTANT_WORD7_0__TYPE_shift = 30,
+ EG_SQ_VTX_CONSTANT_WORD7_0__TYPE_mask = 0x3 << 30,
+ /* SQ_TEX_SAMPLER_WORD0_0 */
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift = 0, // 3;
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask = 0x7,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Y_shift = 3, // 3;
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Y_mask = 0x7 << 3,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Z_shift = 6, // 3;
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Z_mask = 0x7 << 6,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_shift = 9, // 2;
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_mask = 0x3 << 9,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift = 11, // 2;
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask = 0x3 << 11,
+ EG_SQ_TEX_SAMPLER_WORD0_0__Z_FILTER_shift = 13, // 2;
+ EG_SQ_TEX_SAMPLER_WORD0_0__Z_FILTER_mask = 0x3 << 13,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift = 15, // 2;
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask = 0x3 << 15,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MAX_ANISO_RATIO_shift = 17, // 3;
+ EG_SQ_TEX_SAMPLER_WORD0_0__MAX_ANISO_RATIO_mask = 0x7 << 17,
+ EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_shift = 20,//2;
+ EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_mask = 0x3 << 20,
+ EG_SQ_TEX_SAMPLER_WORD0_0__DCF_shift = 22, // 3;
+ EG_SQ_TEX_SAMPLER_WORD0_0__DCF_mask = 0x7 << 22,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CHROMA_KEY_shift = 25, // 2;
+ EG_SQ_TEX_SAMPLER_WORD0_0__CHROMA_KEY_mask = 0x3 << 25,
+ EG_SQ_TEX_SAMPLER_WORD0_0__ANISO_THRESHOLD_shift = 27, // 3;
+ EG_SQ_TEX_SAMPLER_WORD0_0__ANISO_THRESHOLD_mask = 0x7 << 27,
+ EG_SQ_TEX_SAMPLER_WORD0_0__Reserved_shift = 30, // 2
+ EG_SQ_TEX_SAMPLER_WORD0_0__Reserved_mask = 0x3 << 30,
+ /* SQ_TEX_SAMPLER_WORD1_0 */
+ EG_SQ_TEX_SAMPLER_WORD1_0__MIN_LOD_shift = 0, // 12;
+ EG_SQ_TEX_SAMPLER_WORD1_0__MIN_LOD_mask = 0xfff,
+ EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_shift = 12,// 12;
+ EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_mask = 0xfff << 12,
+ /* SQ_TEX_SAMPLER_WORD2_0 */
+ EG_SQ_TEX_SAMPLER_WORD2_0__LOD_BIAS_shift = 0, //14;
+ EG_SQ_TEX_SAMPLER_WORD2_0__LOD_BIAS_mask = 0x3fff,
+ EG_SQ_TEX_SAMPLER_WORD2_0__LOD_BIAS_SEC_shift = 14,//6;
+ EG_SQ_TEX_SAMPLER_WORD2_0__LOD_BIAS_SEC_mask = 0x3f << 14,
+ EG_SQ_TEX_SAMPLER_WORD2_0__MC_COORD_TRUNCATE_shift = 20,//1;
+ EG_SQ_TEX_SAMPLER_WORD2_0__MC_COORD_TRUNCATE_bit = 1 << 20,
+ EG_SQ_TEX_SAMPLER_WORD2_0__FORCE_DEGAMMA_shift = 21,//1;
+ EG_SQ_TEX_SAMPLER_WORD2_0__FORCE_DEGAMMA_bit = 1 << 21,
+ EG_SQ_TEX_SAMPLER_WORD2_0__ANISO_BIAS_shift = 22,//6;
+ EG_SQ_TEX_SAMPLER_WORD2_0__ANISO_BIAS_mask = 0x3f << 22,
+ EG_SQ_TEX_SAMPLER_WORD2_0__TRUNCATE_COORD_shift = 28,//1;
+ EG_SQ_TEX_SAMPLER_WORD2_0__TRUNCATE_COORD_bit = 1 << 28,
+ EG_SQ_TEX_SAMPLER_WORD2_0__DISABLE_CUBE_WRAP_shift = 29,//1;
+ EG_SQ_TEX_SAMPLER_WORD2_0__DISABLE_CUBE_WRAP_bit = 1 << 29,
+ EG_SQ_TEX_SAMPLER_WORD2_0__Reserved_shift = 30,//1;
+ EG_SQ_TEX_SAMPLER_WORD2_0__Reserved_bit = 1 << 30,
+ EG_SQ_TEX_SAMPLER_WORD2_0__TYPE_shift = 31,//1;
+ EG_SQ_TEX_SAMPLER_WORD2_0__TYPE_bit = 1 << 31,
+ /* SQ_TEX_RESOURCE_WORD0_0 */
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift = 0, // 3;
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask = 0x7,
+ EG_SQ_TEX_RESOURCE_WORD0_0__ISET_shift = 3, // 1;
+ EG_SQ_TEX_RESOURCE_WORD0_0__ISET_bit = 1 << 3,
+ EG_SQ_TEX_RESOURCE_WORD0_0__Reserve_shift = 4, // 1;
+ EG_SQ_TEX_RESOURCE_WORD0_0__Reserve_bit = 1 << 4,
+ EG_SQ_TEX_RESOURCE_WORD0_0__NDTO_shift = 5, // 1;
+ EG_SQ_TEX_RESOURCE_WORD0_0__NDTO_bit = 1 << 5,
+ EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_shift = 6, // 12;
+ EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_mask = 0xfff << 6,
+ EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_shift = 18,// 14;
+ EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_mask = 0x3fff << 18,
+ /* SQ_TEX_RESOURCE_WORD1_0 */
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_shift = 0, // 14;
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_mask = 0x3fff,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift = 14,// 13;
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask = 0x1fff << 14,
+ EG_SQ_TEX_RESOURCE_WORD1_0__Reserved_shift = 27,// 1;
+ EG_SQ_TEX_RESOURCE_WORD1_0__Reserved_bit = 1 << 27,
+ EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift = 28,// 4;
+ EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_mask = 0xf << 28,
+ /* SQ_TEX_RESOURCE_WORD6_0 */
+ EG_SQ_TEX_RESOURCE_WORD6_0__MAX_ANISO_RATIO_shift = 0, //: 3;
+ EG_SQ_TEX_RESOURCE_WORD6_0__MAX_ANISO_RATIO_mask = 0x7,
+ EG_SQ_TEX_RESOURCE_WORD6_0__INTERLACED_shift = 6, //1;
+ EG_SQ_TEX_RESOURCE_WORD6_0__INTERLACED_bit = 1 << 6,
+ EG_SQ_TEX_RESOURCE_WORD6_0__MIN_LOD_shift = 8, //12;
+ EG_SQ_TEX_RESOURCE_WORD6_0__MIN_LOD_mask = 0xfff << 8,
+ EG_SQ_TEX_RESOURCE_WORD6_0__TILE_SPLIT_shift = 29,// 3;
+ EG_SQ_TEX_RESOURCE_WORD6_0__TILE_SPLIT_mask = 0x7 << 29,
+ /* SQ_TEX_RESOURCE_WORD7_0 */
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift = 0, // 6;
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask = 0x3f,
+ EG_SQ_TEX_RESOURCE_WORD7_0__MACRO_TILE_ASPECT_shift = 6, // 2;
+ EG_SQ_TEX_RESOURCE_WORD7_0__MACRO_TILE_ASPECT_mask = 0x3 << 6,
+ EG_SQ_TEX_RESOURCE_WORD7_0__BANK_WIDTH_shift = 8, // 2;
+ EG_SQ_TEX_RESOURCE_WORD7_0__BANK_WIDTH_mask = 0x3 << 8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__BANK_HEIGHT_shift = 10,// 2;
+ EG_SQ_TEX_RESOURCE_WORD7_0__BANK_HEIGHT_mask = 0x3 << 10,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DEPTH_SAMPLE_ORDER_shift = 15,// 1;
+ EG_SQ_TEX_RESOURCE_WORD7_0__DEPTH_SAMPLE_ORDER_bit = 1 << 15,
+ EG_SQ_TEX_RESOURCE_WORD7_0__NUM_BANKS_shift = 16,// 2;
+ EG_SQ_TEX_RESOURCE_WORD7_0__NUM_BANKS_mask = 0x3 << 16,
+ EG_SQ_TEX_RESOURCE_WORD7_0__TYPE_shift = 30,// 2;
+ EG_SQ_TEX_RESOURCE_WORD7_0__TYPE_mask = 0x3 << 30,
+};
+
+/* */
+
+#define EG_SQ_FETCH_RESOURCE_COUNT 0x00000400
+#define EG_SQ_TEX_SAMPLER_COUNT 0x0000006c
+#define EG_SQ_LOOP_CONST_COUNT 0x000000c0
+
+#define EG_SET_RESOURCE_OFFSET 0x30000
+#define EG_SET_RESOURCE_END 0x30400 //r600 := offset + 0x4000
+
+#define EG_SET_LOOP_CONST_OFFSET 0x3A200
+#define EG_SET_LOOP_CONST_END 0x3A26C //r600 := offset + 0x180
+
+
+#define EG_SQ_FETCH_RESOURCE_VS_OFFSET 0x000000b0
+#define EG_FETCH_RESOURCE_STRIDE 8
+
+#define EG_SET_BOOL_CONST_OFFSET 0x3A500
+#define EG_SET_BOOL_CONST_END 0x3A506
+
+
+#endif //_EVERGREEN_DIFF_H_
diff --git a/src/mesa/drivers/dri/r600/evergreen_fragprog.c b/src/mesa/drivers/dri/r600/evergreen_fragprog.c
new file mode 100644
index 00000000000..b53ff424a01
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_fragprog.c
@@ -0,0 +1,817 @@
+/*
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "main/imports.h"
+
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+#include "program/program.h"
+
+#include "r600_context.h"
+#include "r600_cmdbuf.h"
+#include "r600_emit.h"
+
+#include "evergreen_vertprog.h"
+#include "evergreen_fragprog.h"
+
+void evergreen_insert_wpos_code(GLcontext *ctx, struct gl_fragment_program *fprog)
+{
+ static const gl_state_index winstate[STATE_LENGTH]
+ = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0};
+ struct prog_instruction *newInst, *inst;
+ GLint win_size; /* state reference */
+ GLuint wpos_temp; /* temp register */
+ int i, j;
+
+ /* PARAM win_size = STATE_FB_SIZE */
+ win_size = _mesa_add_state_reference(fprog->Base.Parameters, winstate);
+
+ wpos_temp = fprog->Base.NumTemporaries++;
+
+ /* scan program where WPOS is used and replace with wpos_temp */
+ inst = fprog->Base.Instructions;
+ for (i = 0; i < fprog->Base.NumInstructions; i++) {
+ for (j=0; j < 3; j++) {
+ if(inst->SrcReg[j].File == PROGRAM_INPUT &&
+ inst->SrcReg[j].Index == FRAG_ATTRIB_WPOS) {
+ inst->SrcReg[j].File = PROGRAM_TEMPORARY;
+ inst->SrcReg[j].Index = wpos_temp;
+ }
+ }
+ inst++;
+ }
+
+ _mesa_insert_instructions(&(fprog->Base), 0, 1);
+
+ newInst = fprog->Base.Instructions;
+ /* invert wpos.y
+ * wpos_temp.xyzw = wpos.x-yzw + winsize.0y00 */
+ newInst[0].Opcode = OPCODE_ADD;
+ newInst[0].DstReg.File = PROGRAM_TEMPORARY;
+ newInst[0].DstReg.Index = wpos_temp;
+ newInst[0].DstReg.WriteMask = WRITEMASK_XYZW;
+
+ newInst[0].SrcReg[0].File = PROGRAM_INPUT;
+ newInst[0].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
+ newInst[0].SrcReg[0].Swizzle = SWIZZLE_XYZW;
+ newInst[0].SrcReg[0].Negate = NEGATE_Y;
+
+ newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR;
+ newInst[0].SrcReg[1].Index = win_size;
+ newInst[0].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ZERO);
+
+}
+
+//TODO : Validate FP input with VP output.
+void evergreen_Map_Fragment_Program(r700_AssemblerBase *pAsm,
+ struct gl_fragment_program *mesa_fp,
+ GLcontext *ctx)
+{
+ unsigned int unBit;
+ unsigned int i;
+ GLuint ui;
+
+ /* match fp inputs with vp exports. */
+ struct evergreen_vertex_program_cont *vpc =
+ (struct evergreen_vertex_program_cont *)ctx->VertexProgram._Current;
+ GLbitfield OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+
+ pAsm->number_used_registers = 0;
+
+//Input mapping : mesa_fp->Base.InputsRead set the flag, set in
+ //The flags parsed in parse_attrib_binding. FRAG_ATTRIB_COLx, FRAG_ATTRIB_TEXx, ...
+ //MUST match order in Map_Vertex_Output
+ unBit = 1 << FRAG_ATTRIB_WPOS;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS] = pAsm->number_used_registers++;
+ }
+
+ unBit = 1 << VERT_RESULT_COL0;
+ if(OutputsWritten & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0] = pAsm->number_used_registers++;
+ }
+
+ unBit = 1 << VERT_RESULT_COL1;
+ if(OutputsWritten & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1] = pAsm->number_used_registers++;
+ }
+
+ unBit = 1 << VERT_RESULT_FOGC;
+ if(OutputsWritten & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC] = pAsm->number_used_registers++;
+ }
+
+ for(i=0; i<8; i++)
+ {
+ unBit = 1 << (VERT_RESULT_TEX0 + i);
+ if(OutputsWritten & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i] = pAsm->number_used_registers++;
+ }
+ }
+
+/* order has been taken care of */
+#if 1
+ for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
+ {
+ unBit = 1 << i;
+ if(OutputsWritten & unBit)
+ {
+ pAsm->uiFP_AttributeMap[i-VERT_RESULT_VAR0+FRAG_ATTRIB_VAR0] = pAsm->number_used_registers++;
+ }
+ }
+#else
+ if( (mesa_fp->Base.InputsRead >> FRAG_ATTRIB_VAR0) > 0 )
+ {
+ struct evergreen_vertex_program_cont *vpc =
+ (struct evergreen_vertex_program_cont *)ctx->VertexProgram._Current;
+ struct gl_program_parameter_list * VsVarying = vpc->mesa_program.Base.Varying;
+ struct gl_program_parameter_list * PsVarying = mesa_fp->Base.Varying;
+ struct gl_program_parameter * pVsParam;
+ struct gl_program_parameter * pPsParam;
+ GLuint j, k;
+ GLuint unMaxVarying = 0;
+
+ for(i=0; i<VsVarying->NumParameters; i++)
+ {
+ pAsm->uiFP_AttributeMap[i + FRAG_ATTRIB_VAR0] = 0;
+ }
+
+ for(i=FRAG_ATTRIB_VAR0; i<FRAG_ATTRIB_MAX; i++)
+ {
+ unBit = 1 << i;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ j = i - FRAG_ATTRIB_VAR0;
+ pPsParam = PsVarying->Parameters + j;
+
+ for(k=0; k<VsVarying->NumParameters; k++)
+ {
+ pVsParam = VsVarying->Parameters + k;
+
+ if( strcmp(pPsParam->Name, pVsParam->Name) == 0)
+ {
+ pAsm->uiFP_AttributeMap[i] = pAsm->number_used_registers + k;
+ if(k > unMaxVarying)
+ {
+ unMaxVarying = k;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ pAsm->number_used_registers += unMaxVarying + 1;
+ }
+#endif
+ unBit = 1 << FRAG_ATTRIB_FACE;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FACE] = pAsm->number_used_registers++;
+ }
+
+ unBit = 1 << FRAG_ATTRIB_PNTC;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_PNTC] = pAsm->number_used_registers++;
+ }
+
+ pAsm->uIIns = pAsm->number_used_registers;
+
+/* Map temporary registers (GPRs) */
+ pAsm->starting_temp_register_number = pAsm->number_used_registers;
+
+ if(mesa_fp->Base.NumNativeTemporaries >= mesa_fp->Base.NumTemporaries)
+ {
+ pAsm->number_used_registers += mesa_fp->Base.NumNativeTemporaries;
+ }
+ else
+ {
+ pAsm->number_used_registers += mesa_fp->Base.NumTemporaries;
+ }
+
+/* Output mapping */
+ pAsm->number_of_exports = 0;
+ pAsm->number_of_colorandz_exports = 0; /* don't include stencil and mask out. */
+ pAsm->starting_export_register_number = pAsm->number_used_registers;
+ unBit = 1 << FRAG_RESULT_COLOR;
+ if(mesa_fp->Base.OutputsWritten & unBit)
+ {
+ pAsm->uiFP_OutputMap[FRAG_RESULT_COLOR] = pAsm->number_used_registers++;
+ pAsm->number_of_exports++;
+ pAsm->number_of_colorandz_exports++;
+ }
+ unBit = 1 << FRAG_RESULT_DEPTH;
+ if(mesa_fp->Base.OutputsWritten & unBit)
+ {
+ pAsm->depth_export_register_number = pAsm->number_used_registers;
+ pAsm->uiFP_OutputMap[FRAG_RESULT_DEPTH] = pAsm->number_used_registers++;
+ pAsm->number_of_exports++;
+ pAsm->number_of_colorandz_exports++;
+ pAsm->pR700Shader->depthIsExported = 1;
+ }
+
+ pAsm->pucOutMask = (unsigned char*) MALLOC(pAsm->number_of_exports);
+ for(ui=0; ui<pAsm->number_of_exports; ui++)
+ {
+ pAsm->pucOutMask[ui] = 0x0;
+ }
+
+ pAsm->flag_reg_index = pAsm->number_used_registers++;
+
+ pAsm->uFirstHelpReg = pAsm->number_used_registers;
+}
+
+GLboolean evergreen_Find_Instruction_Dependencies_fp(struct evergreen_fragment_program *fp,
+ struct gl_fragment_program *mesa_fp)
+{
+ GLuint i, j;
+ GLint * puiTEMPwrites;
+ GLint * puiTEMPreads;
+ struct prog_instruction * pILInst;
+ InstDeps *pInstDeps;
+ struct prog_instruction * texcoord_DepInst;
+ GLint nDepInstID;
+
+ puiTEMPwrites = (GLint*) MALLOC(sizeof(GLuint)*mesa_fp->Base.NumTemporaries);
+ puiTEMPreads = (GLint*) MALLOC(sizeof(GLuint)*mesa_fp->Base.NumTemporaries);
+
+ for(i=0; i<mesa_fp->Base.NumTemporaries; i++)
+ {
+ puiTEMPwrites[i] = -1;
+ puiTEMPreads[i] = -1;
+ }
+
+ pInstDeps = (InstDeps*)MALLOC(sizeof(InstDeps)*mesa_fp->Base.NumInstructions);
+
+ for(i=0; i<mesa_fp->Base.NumInstructions; i++)
+ {
+ pInstDeps[i].nDstDep = -1;
+ pILInst = &(mesa_fp->Base.Instructions[i]);
+
+ //Dst
+ if(pILInst->DstReg.File == PROGRAM_TEMPORARY)
+ {
+ //Set lastwrite for the temp
+ puiTEMPwrites[pILInst->DstReg.Index] = i;
+ }
+
+ //Src
+ for(j=0; j<3; j++)
+ {
+ if(pILInst->SrcReg[j].File == PROGRAM_TEMPORARY)
+ {
+ //Set dep.
+ pInstDeps[i].nSrcDeps[j] = puiTEMPwrites[pILInst->SrcReg[j].Index];
+ //Set first read
+ if(puiTEMPreads[pILInst->SrcReg[j].Index] < 0 )
+ {
+ puiTEMPreads[pILInst->SrcReg[j].Index] = i;
+ }
+ }
+ else
+ {
+ pInstDeps[i].nSrcDeps[j] = -1;
+ }
+ }
+ }
+
+ fp->r700AsmCode.pInstDeps = pInstDeps;
+
+ //Find dep for tex inst
+ for(i=0; i<mesa_fp->Base.NumInstructions; i++)
+ {
+ pILInst = &(mesa_fp->Base.Instructions[i]);
+
+ if(GL_TRUE == IsTex(pILInst->Opcode))
+ { //src0 is the tex coord register, src1 is texunit, src2 is textype
+ nDepInstID = pInstDeps[i].nSrcDeps[0];
+ if(nDepInstID >= 0)
+ {
+ texcoord_DepInst = &(mesa_fp->Base.Instructions[nDepInstID]);
+ if(GL_TRUE == IsAlu(texcoord_DepInst->Opcode) )
+ {
+ pInstDeps[nDepInstID].nDstDep = i;
+ pInstDeps[i].nDstDep = i;
+ }
+ else if(GL_TRUE == IsTex(texcoord_DepInst->Opcode) )
+ {
+ pInstDeps[i].nDstDep = i;
+ }
+ else
+ { //... other deps?
+ }
+ }
+ // make sure that we dont overwrite src used earlier
+ nDepInstID = puiTEMPreads[pILInst->DstReg.Index];
+ if(nDepInstID < i)
+ {
+ pInstDeps[i].nDstDep = puiTEMPreads[pILInst->DstReg.Index];
+ texcoord_DepInst = &(mesa_fp->Base.Instructions[nDepInstID]);
+ if(GL_TRUE == IsAlu(texcoord_DepInst->Opcode) )
+ {
+ pInstDeps[nDepInstID].nDstDep = i;
+ }
+
+ }
+
+ }
+ }
+
+ FREE(puiTEMPwrites);
+ FREE(puiTEMPreads);
+
+ return GL_TRUE;
+}
+
+GLboolean evergreenTranslateFragmentShader(struct evergreen_fragment_program *fp,
+ struct gl_fragment_program *mesa_fp,
+ GLcontext *ctx)
+{
+ GLuint number_of_colors_exported;
+ GLboolean z_enabled = GL_FALSE;
+ GLuint unBit, shadow_unit;
+ int i;
+ struct prog_instruction *inst;
+ gl_state_index shadow_ambient[STATE_LENGTH]
+ = { STATE_INTERNAL, STATE_SHADOW_AMBIENT, 0, 0, 0};
+
+ //Init_Program
+ Init_r700_AssemblerBase( SPT_FP, &(fp->r700AsmCode), &(fp->r700Shader) );
+
+ fp->constbo0 = NULL;
+ fp->r700AsmCode.bUseMemConstant = GL_TRUE;
+ fp->r700AsmCode.unAsic = 8;
+
+ if(mesa_fp->Base.InputsRead & FRAG_BIT_WPOS)
+ {
+ evergreen_insert_wpos_code(ctx, mesa_fp);
+ }
+
+ /* add/map consts for ARB_shadow_ambient */
+ if(mesa_fp->Base.ShadowSamplers)
+ {
+ inst = mesa_fp->Base.Instructions;
+ for (i = 0; i < mesa_fp->Base.NumInstructions; i++)
+ {
+ if(inst->TexShadow == 1)
+ {
+ shadow_unit = inst->TexSrcUnit;
+ shadow_ambient[2] = shadow_unit;
+ fp->r700AsmCode.shadow_regs[shadow_unit] =
+ _mesa_add_state_reference(mesa_fp->Base.Parameters, shadow_ambient);
+ }
+ inst++;
+ }
+ }
+
+ evergreen_Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp, ctx);
+
+ if( GL_FALSE == evergreen_Find_Instruction_Dependencies_fp(fp, mesa_fp) )
+ {
+ return GL_FALSE;
+ }
+
+ InitShaderProgram(&(fp->r700AsmCode));
+
+ for(i=0; i < MAX_SAMPLERS; i++)
+ {
+ fp->r700AsmCode.SamplerUnits[i] = fp->mesa_program.Base.SamplerUnits[i];
+ }
+
+ fp->r700AsmCode.unCurNumILInsts = mesa_fp->Base.NumInstructions;
+
+ if( GL_FALSE == AssembleInstr(0,
+ 0,
+ mesa_fp->Base.NumInstructions,
+ &(mesa_fp->Base.Instructions[0]),
+ &(fp->r700AsmCode)) )
+ {
+ return GL_FALSE;
+ }
+
+ if(GL_FALSE == Process_Fragment_Exports(&(fp->r700AsmCode), mesa_fp->Base.OutputsWritten) )
+ {
+ return GL_FALSE;
+ }
+
+ if( GL_FALSE == RelocProgram(&(fp->r700AsmCode), &(mesa_fp->Base)) )
+ {
+ return GL_FALSE;
+ }
+
+ fp->r700Shader.nRegs = (fp->r700AsmCode.number_used_registers == 0) ? 0
+ : (fp->r700AsmCode.number_used_registers - 1);
+
+ fp->r700Shader.nParamExports = fp->r700AsmCode.number_of_exports;
+
+ number_of_colors_exported = fp->r700AsmCode.number_of_colorandz_exports;
+
+ unBit = 1 << FRAG_RESULT_DEPTH;
+ if(mesa_fp->Base.OutputsWritten & unBit)
+ {
+ z_enabled = GL_TRUE;
+ number_of_colors_exported--;
+ }
+
+ /* illegal to set this to 0 */
+ if(number_of_colors_exported || z_enabled)
+ {
+ fp->r700Shader.exportMode = number_of_colors_exported << 1 | z_enabled;
+ }
+ else
+ {
+ fp->r700Shader.exportMode = (1 << 1);
+ }
+
+ fp->translated = GL_TRUE;
+
+ return GL_TRUE;
+}
+
+void evergreenSelectFragmentShader(GLcontext *ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ struct evergreen_fragment_program *fp = (struct evergreen_fragment_program *)
+ (ctx->FragmentProgram._Current);
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ {
+ fp->r700AsmCode.bR6xx = 1;
+ }
+
+ if (GL_FALSE == fp->translated)
+ evergreenTranslateFragmentShader(fp, &(fp->mesa_program), ctx);
+}
+
+void * evergreenGetActiveFpShaderBo(GLcontext * ctx)
+{
+ struct evergreen_fragment_program *fp = (struct evergreen_fragment_program *)
+ (ctx->FragmentProgram._Current);
+
+ return fp->shaderbo;
+}
+
+void * evergreenGetActiveFpShaderConstBo(GLcontext * ctx)
+{
+ struct evergreen_fragment_program *fp = (struct evergreen_fragment_program *)
+ (ctx->FragmentProgram._Current);
+
+ return fp->constbo0;
+}
+
+GLboolean evergreenSetupFragmentProgram(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct evergreen_fragment_program *fp = (struct evergreen_fragment_program *)
+ (ctx->FragmentProgram._Current);
+ r700_AssemblerBase *pAsm = &(fp->r700AsmCode);
+ struct gl_fragment_program *mesa_fp = &(fp->mesa_program);
+ unsigned int ui, i;
+ unsigned int unNumOfReg;
+ unsigned int unBit;
+ GLuint exportCount;
+ GLboolean point_sprite = GL_FALSE;
+
+ if(GL_FALSE == fp->loaded)
+ {
+ if(fp->r700Shader.bNeedsAssembly == GL_TRUE)
+ {
+ Assemble( &(fp->r700Shader) );
+ }
+
+ r600EmitShader(ctx,
+ &(fp->shaderbo),
+ (GLvoid *)(fp->r700Shader.pProgram),
+ fp->r700Shader.uShaderBinaryDWORDSize,
+ "FS");
+
+ fp->loaded = GL_TRUE;
+ }
+
+ /* TODO : enable this after MemUse fixed *=
+ (context->chipobj.MemUse)(context, fp->shadercode.buf->id);
+ */
+
+ EVERGREEN_STATECHANGE(context, sq);
+
+ evergreen->SQ_PGM_RESOURCES_PS.u32All = 0;
+ SETbit(evergreen->SQ_PGM_RESOURCES_PS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
+
+ evergreen->ps.SQ_ALU_CONST_CACHE_PS_0.u32All = 0;
+ evergreen->ps.SQ_PGM_START_PS.u32All = 0;
+
+ EVERGREEN_STATECHANGE(context, spi);
+
+ unNumOfReg = fp->r700Shader.nRegs + 1;
+
+ ui = (evergreen->SPI_PS_IN_CONTROL_0.u32All & NUM_INTERP_mask) / (1 << NUM_INTERP_shift);
+
+ /* PS uses fragment.position */
+ if (mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS))
+ {
+ ui += 1;
+ SETfield(evergreen->SPI_PS_IN_CONTROL_0.u32All, ui, NUM_INTERP_shift, NUM_INTERP_mask);
+ SETfield(evergreen->SPI_PS_IN_CONTROL_0.u32All, CENTERS_ONLY, BARYC_SAMPLE_CNTL_shift, BARYC_SAMPLE_CNTL_mask);
+ SETbit(evergreen->SPI_PS_IN_CONTROL_0.u32All, POSITION_ENA_bit);
+ SETbit(evergreen->SPI_INPUT_Z.u32All, PROVIDE_Z_TO_SPI_bit);
+ }
+ else
+ {
+ CLEARbit(evergreen->SPI_PS_IN_CONTROL_0.u32All, POSITION_ENA_bit);
+ CLEARbit(evergreen->SPI_INPUT_Z.u32All, PROVIDE_Z_TO_SPI_bit);
+ }
+
+ if (mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_FACE))
+ {
+ ui += 1;
+ SETfield(evergreen->SPI_PS_IN_CONTROL_0.u32All, ui, NUM_INTERP_shift, NUM_INTERP_mask);
+ SETbit(evergreen->SPI_PS_IN_CONTROL_1.u32All, FRONT_FACE_ENA_bit);
+ SETbit(evergreen->SPI_PS_IN_CONTROL_1.u32All, FRONT_FACE_ALL_BITS_bit);
+ SETfield(evergreen->SPI_PS_IN_CONTROL_1.u32All, pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FACE], FRONT_FACE_ADDR_shift, FRONT_FACE_ADDR_mask);
+ }
+ else
+ {
+ CLEARbit(evergreen->SPI_PS_IN_CONTROL_1.u32All, FRONT_FACE_ENA_bit);
+ }
+
+ /* see if we need any point_sprite replacements */
+ for (i = VERT_RESULT_TEX0; i<= VERT_RESULT_TEX7; i++)
+ {
+ if(ctx->Point.CoordReplace[i - VERT_RESULT_TEX0] == GL_TRUE)
+ point_sprite = GL_TRUE;
+ }
+
+ if ((mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_PNTC)) || point_sprite)
+ {
+ /* for FRAG_ATTRIB_PNTC we need to increase num_interp */
+ if(mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_PNTC))
+ {
+ ui++;
+ SETfield(evergreen->SPI_PS_IN_CONTROL_0.u32All, ui, NUM_INTERP_shift, NUM_INTERP_mask);
+ }
+ SETbit(evergreen->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_ENA_bit);
+ SETfield(evergreen->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_S, PNT_SPRITE_OVRD_X_shift, PNT_SPRITE_OVRD_X_mask);
+ SETfield(evergreen->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_T, PNT_SPRITE_OVRD_Y_shift, PNT_SPRITE_OVRD_Y_mask);
+ SETfield(evergreen->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_0, PNT_SPRITE_OVRD_Z_shift, PNT_SPRITE_OVRD_Z_mask);
+ SETfield(evergreen->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_1, PNT_SPRITE_OVRD_W_shift, PNT_SPRITE_OVRD_W_mask);
+ if(ctx->Point.SpriteOrigin == GL_LOWER_LEFT)
+ SETbit(evergreen->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_TOP_1_bit);
+ else
+ CLEARbit(evergreen->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_TOP_1_bit);
+ }
+ else
+ {
+ CLEARbit(evergreen->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_ENA_bit);
+ }
+
+
+ ui = (unNumOfReg < ui) ? ui : unNumOfReg;
+
+ SETfield(evergreen->SQ_PGM_RESOURCES_PS.u32All, ui, NUM_GPRS_shift, NUM_GPRS_mask);
+
+ CLEARbit(evergreen->SQ_PGM_RESOURCES_PS.u32All, UNCACHED_FIRST_INST_bit);
+
+ if(fp->r700Shader.uStackSize) /* we don't use branch for now, it should be zero. */
+ {
+ SETfield(evergreen->SQ_PGM_RESOURCES_PS.u32All, fp->r700Shader.uStackSize,
+ STACK_SIZE_shift, STACK_SIZE_mask);
+ }
+
+ SETfield(evergreen->SQ_PGM_EXPORTS_PS.u32All, fp->r700Shader.exportMode,
+ EXPORT_MODE_shift, EXPORT_MODE_mask);
+
+ // emit ps input map
+ struct evergreen_vertex_program_cont *vpc =
+ (struct evergreen_vertex_program_cont *)ctx->VertexProgram._Current;
+ GLbitfield OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+
+ for(ui = 0; ui < EVERGREEN_MAX_SHADER_EXPORTS; ui++)
+ evergreen->SPI_PS_INPUT_CNTL[ui].u32All = 0;
+
+ unBit = 1 << FRAG_ATTRIB_WPOS;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS];
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (evergreen->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+
+ unBit = 1 << VERT_RESULT_COL0;
+ if(OutputsWritten & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0];
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (evergreen->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+
+ unBit = 1 << VERT_RESULT_COL1;
+ if(OutputsWritten & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1];
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (evergreen->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+
+ unBit = 1 << VERT_RESULT_FOGC;
+ if(OutputsWritten & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC];
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (evergreen->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+
+ for(i=0; i<8; i++)
+ {
+ unBit = 1 << (VERT_RESULT_TEX0 + i);
+ if(OutputsWritten & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i];
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ CLEARbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ /* ARB_point_sprite */
+ if(ctx->Point.CoordReplace[i] == GL_TRUE)
+ {
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, PT_SPRITE_TEX_bit);
+ }
+ }
+ }
+
+ unBit = 1 << FRAG_ATTRIB_FACE;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FACE];
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (evergreen->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+ unBit = 1 << FRAG_ATTRIB_PNTC;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_PNTC];
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (evergreen->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, PT_SPRITE_TEX_bit);
+ }
+
+
+
+
+ for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
+ {
+ unBit = 1 << i;
+ if(OutputsWritten & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[i-VERT_RESULT_VAR0+FRAG_ATTRIB_VAR0];
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (evergreen->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(evergreen->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+ }
+
+ exportCount = (evergreen->SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift);
+
+ return GL_TRUE;
+}
+
+GLboolean evergreenSetupFPconstants(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct evergreen_fragment_program *fp = (struct evergreen_fragment_program *)
+ (ctx->FragmentProgram._Current);
+ r700_AssemblerBase *pAsm = &(fp->r700AsmCode);
+
+ struct gl_program_parameter_list *paramList;
+ unsigned int unNumParamData;
+ unsigned int ui;
+
+ /* sent out shader constants. */
+ paramList = fp->mesa_program.Base.Parameters;
+
+ if(NULL != paramList)
+ {
+ _mesa_load_state_parameters(ctx, paramList);
+
+ if (paramList->NumParameters > EVERGREEN_MAX_DX9_CONSTS)
+ return GL_FALSE;
+
+ EVERGREEN_STATECHANGE(context, sq);
+
+ evergreen->ps.num_consts = paramList->NumParameters;
+
+ unNumParamData = paramList->NumParameters;
+
+ for(ui=0; ui<unNumParamData; ui++) {
+ evergreen->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
+ evergreen->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
+ evergreen->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
+ evergreen->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+ }
+
+ /* Load fp constants to gpu */
+ if(unNumParamData > 0)
+ {
+ radeonAllocDmaRegion(&context->radeon,
+ &context->fp_Constbo,
+ &context->fp_bo_offset,
+ 256,
+ 256);
+ r600EmitShaderConsts(ctx,
+ context->fp_Constbo,
+ context->fp_bo_offset,
+ (GLvoid *)&(evergreen->ps.consts[0][0]),
+ unNumParamData * 4 * 4);
+ }
+ } else
+ evergreen->ps.num_consts = 0;
+
+ COMPILED_SUB * pCompiledSub;
+ GLuint uj;
+ GLuint unConstOffset = evergreen->ps.num_consts;
+ for(ui=0; ui<pAsm->unNumPresub; ui++)
+ {
+ pCompiledSub = pAsm->presubs[ui].pCompiledSub;
+
+ evergreen->ps.num_consts += pCompiledSub->NumParameters;
+
+ for(uj=0; uj<pCompiledSub->NumParameters; uj++)
+ {
+ evergreen->ps.consts[uj + unConstOffset][0].f32All = pCompiledSub->ParameterValues[uj][0];
+ evergreen->ps.consts[uj + unConstOffset][1].f32All = pCompiledSub->ParameterValues[uj][1];
+ evergreen->ps.consts[uj + unConstOffset][2].f32All = pCompiledSub->ParameterValues[uj][2];
+ evergreen->ps.consts[uj + unConstOffset][3].f32All = pCompiledSub->ParameterValues[uj][3];
+ }
+ unConstOffset += pCompiledSub->NumParameters;
+ }
+} \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/evergreen_fragprog.h b/src/mesa/drivers/dri/r600/evergreen_fragprog.h
new file mode 100644
index 00000000000..0e200bf3833
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_fragprog.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#ifndef _EVERGREEN_FRAGPROG_H_
+#define _EVERGREEN_FRAGPROG_H_
+
+#include "r600_context.h"
+#include "r700_assembler.h"
+
+struct evergreen_fragment_program
+{
+ struct gl_fragment_program mesa_program;
+
+ r700_AssemblerBase r700AsmCode;
+ R700_Shader r700Shader;
+
+ GLboolean translated;
+ GLboolean loaded;
+ GLboolean error;
+
+ void * shaderbo;
+
+ GLuint k0used;
+ void * constbo0;
+
+ GLboolean WritesDepth;
+ GLuint optimization;
+};
+
+/* Internal */
+void evergreen_insert_wpos_code(GLcontext *ctx, struct gl_fragment_program *fprog);
+
+void evergreen_Map_Fragment_Program(r700_AssemblerBase *pAsm,
+ struct gl_fragment_program *mesa_fp,
+ GLcontext *ctx);
+GLboolean evergreen_Find_Instruction_Dependencies_fp(struct evergreen_fragment_program *fp,
+ struct gl_fragment_program *mesa_fp);
+
+GLboolean evergreenTranslateFragmentShader(struct evergreen_fragment_program *fp,
+ struct gl_fragment_program *mesa_vp,
+ GLcontext *ctx);
+
+/* Interface */
+extern void evergreenSelectFragmentShader(GLcontext *ctx);
+
+extern GLboolean evergreenSetupFragmentProgram(GLcontext * ctx);
+
+extern GLboolean evergreenSetupFPconstants(GLcontext * ctx);
+
+extern void * evergreenGetActiveFpShaderBo(GLcontext * ctx);
+
+extern void * evergreenGetActiveFpShaderConstBo(GLcontext * ctx);
+
+#endif /*_EVERGREEN_FRAGPROG_H_*/
diff --git a/src/mesa/slang/slang_emit.h b/src/mesa/drivers/dri/r600/evergreen_ioctl.c
index f93d6b00d69..5c1270790df 100644
--- a/src/mesa/slang/slang_emit.h
+++ b/src/mesa/drivers/dri/r600/evergreen_ioctl.c
@@ -1,8 +1,5 @@
/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -17,33 +14,40 @@
* 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
+ * THE COPYRIGHT HOLDER(S) 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 SLANG_EMIT_H
-#define SLANG_EMIT_H
-
-#include "main/glheader.h"
-#include "slang_ir.h"
-#include "slang_vartable.h"
-
+/*
+ * Authors:
+ */
-extern GLuint
-_slang_swizzle_swizzle(GLuint swz1, GLuint swz2);
+#include <sched.h>
+#include <errno.h>
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/context.h"
+#include "main/simple_list.h"
-extern GLuint
-_slang_var_swizzle(GLint size, GLint comp);
+#include "radeon_common.h"
+#include "r600_context.h"
+#include "evergreen_ioctl.h"
-extern GLboolean
-_slang_emit_code(slang_ir_node *n, slang_var_table *vartable,
- struct gl_program *prog,
- const struct gl_sl_pragmas *pragmas,
- GLboolean withEnd,
- slang_info_log *log);
+#include "r700_clear.h"
+void evergreenClear(GLcontext * ctx, GLbitfield mask)
+{
+ r700Clear(ctx, mask);
+}
-#endif /* SLANG_EMIT_H */
+void evergreenInitIoctlFuncs(struct dd_function_table *functions)
+{
+ functions->Clear = evergreenClear;
+ functions->Finish = radeonFinish;
+ functions->Flush = radeonFlush;
+}
diff --git a/src/mesa/slang/slang_mem.h b/src/mesa/drivers/dri/r600/evergreen_ioctl.h
index b5bfae24791..3c663a7083a 100644
--- a/src/mesa/slang/slang_mem.h
+++ b/src/mesa/drivers/dri/r600/evergreen_ioctl.h
@@ -1,8 +1,5 @@
/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -17,39 +14,23 @@
* 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
-#ifndef SLANG_MEM_H
-#define SLANG_MEM_H
-
-
-#include "main/imports.h"
-
-
-typedef struct slang_mempool_ slang_mempool;
-
-
-extern slang_mempool *
-_slang_new_mempool(GLuint initialSize);
-
-extern void
-_slang_delete_mempool(slang_mempool *pool);
-
-extern void *
-_slang_alloc(GLuint bytes);
-
-extern void *
-_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize);
-
-extern char *
-_slang_strdup(const char *s);
+#ifndef _EVERGREEN_IOCTL_H_
+#define _EVERGREEN_IOCTL_H_
-extern void
-_slang_free(void *addr);
+#include "r600_context.h"
+#include "radeon_drm.h"
+extern void evergreenClear(GLcontext * ctx, GLbitfield mask);
+extern void evergreenInitIoctlFuncs(struct dd_function_table *functions);
-#endif
+#endif /* _EVERGREEN_IOCTL_H_ */
diff --git a/src/mesa/drivers/dri/r600/evergreen_off.h b/src/mesa/drivers/dri/r600/evergreen_off.h
new file mode 100644
index 00000000000..8c250699ec6
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_off.h
@@ -0,0 +1,881 @@
+/*
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#ifndef _EVERGREEN_OFF_H_
+#define _EVERGREEN_OFF_H_
+
+enum
+{
+/* Registers from PA block: */
+ EG_PA_SC_SCREEN_SCISSOR_TL = 0x28030, // DIFF
+ EG_PA_SC_SCREEN_SCISSOR_BR = 0x28034, // DIFF
+ EG_PA_SC_WINDOW_OFFSET = 0x28200, // DIFF
+ EG_PA_SC_WINDOW_SCISSOR_TL = 0x28204, // DIFF
+ EG_PA_SC_WINDOW_SCISSOR_BR = 0x28208, // DIFF
+ EG_PA_SC_CLIPRECT_RULE = 0x2820C, // SAME
+ EG_PA_SC_CLIPRECT_0_TL = 0x28210, // DIFF
+ EG_PA_SC_CLIPRECT_0_BR = 0x28214, // DIFF
+ EG_PA_SC_CLIPRECT_1_TL = 0x28218, // DIFF
+ EG_PA_SC_CLIPRECT_1_BR = 0x2821C, // DIFF
+ EG_PA_SC_CLIPRECT_2_TL = 0x28220, // DIFF
+ EG_PA_SC_CLIPRECT_2_BR = 0x28224, // DIFF
+ EG_PA_SC_CLIPRECT_3_TL = 0x28228, // DIFF
+ EG_PA_SC_CLIPRECT_3_BR = 0x2822C, // DIFF
+ EG_PA_SC_EDGERULE = 0x28230, // SAME
+ EG_PA_SU_HARDWARE_SCREEN_OFFSET = 0x28234, //
+ EG_PA_SC_GENERIC_SCISSOR_TL = 0x28240, // DIFF
+ EG_PA_SC_GENERIC_SCISSOR_BR = 0x28244, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_0_TL = 0x28250, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_0_BR = 0x28254, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_1_TL = 0x28258, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_1_BR = 0x2825C, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_2_TL = 0x28260, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_2_BR = 0x28264, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_3_TL = 0x28268, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_3_BR = 0x2826C, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_4_TL = 0x28270, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_4_BR = 0x28274, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_5_TL = 0x28278, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_5_BR = 0x2827C, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_6_TL = 0x28280, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_6_BR = 0x28284, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_7_TL = 0x28288, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_7_BR = 0x2828C, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_8_TL = 0x28290, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_8_BR = 0x28294, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_9_TL = 0x28298, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_9_BR = 0x2829C, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_10_TL = 0x282A0, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_10_BR = 0x282A4, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_11_TL = 0x282A8, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_11_BR = 0x282AC, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_12_TL = 0x282B0, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_12_BR = 0x282B4, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_13_TL = 0x282B8, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_13_BR = 0x282BC, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_14_TL = 0x282C0, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_14_BR = 0x282C4, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_15_TL = 0x282C8, // DIFF
+ EG_PA_SC_VPORT_SCISSOR_15_BR = 0x282CC, // DIFF
+ EG_PA_SC_VPORT_ZMIN_0 = 0x282D0, // SAME
+ EG_PA_SC_VPORT_ZMAX_0 = 0x282D4, // SAME
+ EG_PA_SC_VPORT_ZMIN_1 = 0x282D8, // SAME
+ EG_PA_SC_VPORT_ZMAX_1 = 0x282DC, // SAME
+ EG_PA_SC_VPORT_ZMIN_2 = 0x282E0, // SAME
+ EG_PA_SC_VPORT_ZMAX_2 = 0x282E4, // SAME
+ EG_PA_SC_VPORT_ZMIN_3 = 0x282E8, // SAME
+ EG_PA_SC_VPORT_ZMAX_3 = 0x282EC, // SAME
+ EG_PA_SC_VPORT_ZMIN_4 = 0x282F0, // SAME
+ EG_PA_SC_VPORT_ZMAX_4 = 0x282F4, // SAME
+ EG_PA_SC_VPORT_ZMIN_5 = 0x282F8, // SAME
+ EG_PA_SC_VPORT_ZMAX_5 = 0x282FC, // SAME
+ EG_PA_SC_VPORT_ZMIN_6 = 0x28300, // SAME
+ EG_PA_SC_VPORT_ZMAX_6 = 0x28304, // SAME
+ EG_PA_SC_VPORT_ZMIN_7 = 0x28308, // SAME
+ EG_PA_SC_VPORT_ZMAX_7 = 0x2830C, // SAME
+ EG_PA_SC_VPORT_ZMIN_8 = 0x28310, // SAME
+ EG_PA_SC_VPORT_ZMAX_8 = 0x28314, // SAME
+ EG_PA_SC_VPORT_ZMIN_9 = 0x28318, // SAME
+ EG_PA_SC_VPORT_ZMAX_9 = 0x2831C, // SAME
+ EG_PA_SC_VPORT_ZMIN_10 = 0x28320, // SAME
+ EG_PA_SC_VPORT_ZMAX_10 = 0x28324, // SAME
+ EG_PA_SC_VPORT_ZMIN_11 = 0x28328, // SAME
+ EG_PA_SC_VPORT_ZMAX_11 = 0x2832C, // SAME
+ EG_PA_SC_VPORT_ZMIN_12 = 0x28330, // SAME
+ EG_PA_SC_VPORT_ZMAX_12 = 0x28334, // SAME
+ EG_PA_SC_VPORT_ZMIN_13 = 0x28338, // SAME
+ EG_PA_SC_VPORT_ZMAX_13 = 0x2833C, // SAME
+ EG_PA_SC_VPORT_ZMIN_14 = 0x28340, // SAME
+ EG_PA_SC_VPORT_ZMAX_14 = 0x28344, // SAME
+ EG_PA_SC_VPORT_ZMIN_15 = 0x28348, // SAME
+ EG_PA_SC_VPORT_ZMAX_15 = 0x2834C, // SAME
+ EG_PA_CL_VPORT_XSCALE = 0x2843C, // SAME
+ EG_PA_CL_VPORT_XOFFSET = 0x28440, // SAME
+ EG_PA_CL_VPORT_YSCALE = 0x28444, // SAME
+ EG_PA_CL_VPORT_YOFFSET = 0x28448, // SAME
+ EG_PA_CL_VPORT_ZSCALE = 0x2844C, // SAME
+ EG_PA_CL_VPORT_ZOFFSET = 0x28450, // SAME
+ EG_PA_CL_VPORT_XSCALE_1 = 0x28454, // SAME
+ EG_PA_CL_VPORT_XOFFSET_1 = 0x28458, // SAME
+ EG_PA_CL_VPORT_YSCALE_1 = 0x2845C, // SAME
+ EG_PA_CL_VPORT_YOFFSET_1 = 0x28460, // SAME
+ EG_PA_CL_VPORT_ZSCALE_1 = 0x28464, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_1 = 0x28468, // SAME
+ EG_PA_CL_VPORT_XSCALE_2 = 0x2846C, // SAME
+ EG_PA_CL_VPORT_XOFFSET_2 = 0x28470, // SAME
+ EG_PA_CL_VPORT_YSCALE_2 = 0x28474, // SAME
+ EG_PA_CL_VPORT_YOFFSET_2 = 0x28478, // SAME
+ EG_PA_CL_VPORT_ZSCALE_2 = 0x2847C, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_2 = 0x28480, // SAME
+ EG_PA_CL_VPORT_XSCALE_3 = 0x28484, // SAME
+ EG_PA_CL_VPORT_XOFFSET_3 = 0x28488, // SAME
+ EG_PA_CL_VPORT_YSCALE_3 = 0x2848C, // SAME
+ EG_PA_CL_VPORT_YOFFSET_3 = 0x28490, // SAME
+ EG_PA_CL_VPORT_ZSCALE_3 = 0x28494, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_3 = 0x28498, // SAME
+ EG_PA_CL_VPORT_XSCALE_4 = 0x2849C, // SAME
+ EG_PA_CL_VPORT_XOFFSET_4 = 0x284A0, // SAME
+ EG_PA_CL_VPORT_YSCALE_4 = 0x284A4, // SAME
+ EG_PA_CL_VPORT_YOFFSET_4 = 0x284A8, // SAME
+ EG_PA_CL_VPORT_ZSCALE_4 = 0x284AC, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_4 = 0x284B0, // SAME
+ EG_PA_CL_VPORT_XSCALE_5 = 0x284B4, // SAME
+ EG_PA_CL_VPORT_XOFFSET_5 = 0x284B8, // SAME
+ EG_PA_CL_VPORT_YSCALE_5 = 0x284BC, // SAME
+ EG_PA_CL_VPORT_YOFFSET_5 = 0x284C0, // SAME
+ EG_PA_CL_VPORT_ZSCALE_5 = 0x284C4, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_5 = 0x284C8, // SAME
+ EG_PA_CL_VPORT_XSCALE_6 = 0x284CC, // SAME
+ EG_PA_CL_VPORT_XOFFSET_6 = 0x284D0, // SAME
+ EG_PA_CL_VPORT_YSCALE_6 = 0x284D4, // SAME
+ EG_PA_CL_VPORT_YOFFSET_6 = 0x284D8, // SAME
+ EG_PA_CL_VPORT_ZSCALE_6 = 0x284DC, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_6 = 0x284E0, // SAME
+ EG_PA_CL_VPORT_XSCALE_7 = 0x284E4, // SAME
+ EG_PA_CL_VPORT_XOFFSET_7 = 0x284E8, // SAME
+ EG_PA_CL_VPORT_YSCALE_7 = 0x284EC, // SAME
+ EG_PA_CL_VPORT_YOFFSET_7 = 0x284F0, // SAME
+ EG_PA_CL_VPORT_ZSCALE_7 = 0x284F4, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_7 = 0x284F8, // SAME
+ EG_PA_CL_VPORT_XSCALE_8 = 0x284FC, // SAME
+ EG_PA_CL_VPORT_XOFFSET_8 = 0x28500, // SAME
+ EG_PA_CL_VPORT_YSCALE_8 = 0x28504, // SAME
+ EG_PA_CL_VPORT_YOFFSET_8 = 0x28508, // SAME
+ EG_PA_CL_VPORT_ZSCALE_8 = 0x2850C, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_8 = 0x28510, // SAME
+ EG_PA_CL_VPORT_XSCALE_9 = 0x28514, // SAME
+ EG_PA_CL_VPORT_XOFFSET_9 = 0x28518, // SAME
+ EG_PA_CL_VPORT_YSCALE_9 = 0x2851C, // SAME
+ EG_PA_CL_VPORT_YOFFSET_9 = 0x28520, // SAME
+ EG_PA_CL_VPORT_ZSCALE_9 = 0x28524, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_9 = 0x28528, // SAME
+ EG_PA_CL_VPORT_XSCALE_10 = 0x2852C, // SAME
+ EG_PA_CL_VPORT_XOFFSET_10 = 0x28530, // SAME
+ EG_PA_CL_VPORT_YSCALE_10 = 0x28534, // SAME
+ EG_PA_CL_VPORT_YOFFSET_10 = 0x28538, // SAME
+ EG_PA_CL_VPORT_ZSCALE_10 = 0x2853C, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_10 = 0x28540, // SAME
+ EG_PA_CL_VPORT_XSCALE_11 = 0x28544, // SAME
+ EG_PA_CL_VPORT_XOFFSET_11 = 0x28548, // SAME
+ EG_PA_CL_VPORT_YSCALE_11 = 0x2854C, // SAME
+ EG_PA_CL_VPORT_YOFFSET_11 = 0x28550, // SAME
+ EG_PA_CL_VPORT_ZSCALE_11 = 0x28554, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_11 = 0x28558, // SAME
+ EG_PA_CL_VPORT_XSCALE_12 = 0x2855C, // SAME
+ EG_PA_CL_VPORT_XOFFSET_12 = 0x28560, // SAME
+ EG_PA_CL_VPORT_YSCALE_12 = 0x28564, // SAME
+ EG_PA_CL_VPORT_YOFFSET_12 = 0x28568, // SAME
+ EG_PA_CL_VPORT_ZSCALE_12 = 0x2856C, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_12 = 0x28570, // SAME
+ EG_PA_CL_VPORT_XSCALE_13 = 0x28574, // SAME
+ EG_PA_CL_VPORT_XOFFSET_13 = 0x28578, // SAME
+ EG_PA_CL_VPORT_YSCALE_13 = 0x2857C, // SAME
+ EG_PA_CL_VPORT_YOFFSET_13 = 0x28580, // SAME
+ EG_PA_CL_VPORT_ZSCALE_13 = 0x28584, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_13 = 0x28588, // SAME
+ EG_PA_CL_VPORT_XSCALE_14 = 0x2858C, // SAME
+ EG_PA_CL_VPORT_XOFFSET_14 = 0x28590, // SAME
+ EG_PA_CL_VPORT_YSCALE_14 = 0x28594, // SAME
+ EG_PA_CL_VPORT_YOFFSET_14 = 0x28598, // SAME
+ EG_PA_CL_VPORT_ZSCALE_14 = 0x2859C, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_14 = 0x285A0, // SAME
+ EG_PA_CL_VPORT_XSCALE_15 = 0x285A4, // SAME
+ EG_PA_CL_VPORT_XOFFSET_15 = 0x285A8, // SAME
+ EG_PA_CL_VPORT_YSCALE_15 = 0x285AC, // SAME
+ EG_PA_CL_VPORT_YOFFSET_15 = 0x285B0, // SAME
+ EG_PA_CL_VPORT_ZSCALE_15 = 0x285B4, // SAME
+ EG_PA_CL_VPORT_ZOFFSET_15 = 0x285B8, // SAME
+ EG_PA_CL_UCP_0_X = 0x285BC, // SAME 0x28E20
+ EG_PA_CL_UCP_0_Y = 0x285C0, // SAME 0x28E24
+ EG_PA_CL_UCP_0_Z = 0x285C4, // SAME 0x28E28
+ EG_PA_CL_UCP_0_W = 0x285C8, // SAME 0x28E2C
+ EG_PA_CL_UCP_1_X = 0x285CC, // SAME 0x28E30
+ EG_PA_CL_UCP_1_Y = 0x285D0, // SAME 0x28E34
+ EG_PA_CL_UCP_1_Z = 0x285D4, // SAME 0x28E38
+ EG_PA_CL_UCP_1_W = 0x285D8, // SAME 0x28E3C
+ EG_PA_CL_UCP_2_X = 0x285DC, // SAME 0x28E40
+ EG_PA_CL_UCP_2_Y = 0x285E0, // SAME 0x28E44
+ EG_PA_CL_UCP_2_Z = 0x285E4, // SAME 0x28E48
+ EG_PA_CL_UCP_2_W = 0x285E8, // SAME 0x28E4C
+ EG_PA_CL_UCP_3_X = 0x285EC, // SAME 0x28E50
+ EG_PA_CL_UCP_3_Y = 0x285F0, // SAME 0x28E54
+ EG_PA_CL_UCP_3_Z = 0x285F4, // SAME 0x28E58
+ EG_PA_CL_UCP_3_W = 0x285F8, // SAME 0x28E5C
+ EG_PA_CL_UCP_4_X = 0x285FC, // SAME 0x28E60
+ EG_PA_CL_UCP_4_Y = 0x28600, // SAME 0x28E64
+ EG_PA_CL_UCP_4_Z = 0x28604, // SAME 0x28E68
+ EG_PA_CL_UCP_4_W = 0x28608, // SAME 0x28E6C
+ EG_PA_CL_UCP_5_X = 0x2860C, // SAME 0x28E70
+ EG_PA_CL_UCP_5_Y = 0x28610, // SAME 0x28E74
+ EG_PA_CL_UCP_5_Z = 0x28614, // SAME 0x28E78
+ EG_PA_CL_UCP_5_W = 0x28618, // SAME 0x28E7C
+ EG_PA_CL_POINT_X_RAD = 0x287D4, // SAME 0x28E10
+ EG_PA_CL_POINT_Y_RAD = 0x287D8, // SAME 0x28E14
+ EG_PA_CL_POINT_SIZE = 0x287DC, // SAME 0x28E18
+ EG_PA_CL_POINT_CULL_RAD = 0x287E0, // SAME 0x28E1C
+ EG_PA_CL_CLIP_CNTL = 0x28810, // SAME
+ EG_PA_SU_SC_MODE_CNTL = 0x28814, // SAME
+ EG_PA_CL_VTE_CNTL = 0x28818, // SAME
+ EG_PA_CL_VS_OUT_CNTL = 0x2881C, // SAME
+ EG_PA_CL_NANINF_CNTL = 0x28820, // SAME
+ EG_PA_SU_LINE_STIPPLE_CNTL = 0x28824, //
+ EG_PA_SU_LINE_STIPPLE_SCALE = 0x28828, //
+ EG_PA_SU_PRIM_FILTER_CNTL = 0x2882C, //
+ EG_PA_SU_POINT_SIZE = 0x28A00, // SAME
+ EG_PA_SU_POINT_MINMAX = 0x28A04, // SAME
+ EG_PA_SU_LINE_CNTL = 0x28A08, // SAME
+ EG_PA_SC_LINE_STIPPLE = 0x28A0C, // SAME
+ EG_PA_SC_MODE_CNTL_0 = 0x28A48, //
+ EG_PA_SC_MODE_CNTL_1 = 0x28A4C, //
+ EG_PA_SU_POLY_OFFSET_DB_FMT_CNTL = 0x28B78, // SAME 0x28DF8
+ EG_PA_SU_POLY_OFFSET_CLAMP = 0x28B7C, // SAME 0x28DFC
+ EG_PA_SU_POLY_OFFSET_FRONT_SCALE = 0x28B80, // SAME 0x28E00
+ EG_PA_SU_POLY_OFFSET_FRONT_OFFSET = 0x28B84, // SAME 0x28E04
+ EG_PA_SU_POLY_OFFSET_BACK_SCALE = 0x28B88, // SAME 0x28E08
+ EG_PA_SU_POLY_OFFSET_BACK_OFFSET = 0x28B8C, // SAME 0x28E0C
+ EG_PA_SC_LINE_CNTL = 0x28C00, // DIFF
+ EG_PA_SC_AA_CONFIG = 0x28C04, // SAME
+ EG_PA_SU_VTX_CNTL = 0x28C08, // SAME
+ EG_PA_CL_GB_VERT_CLIP_ADJ = 0x28C0C, // SAME
+ EG_PA_CL_GB_VERT_DISC_ADJ = 0x28C10, // SAME
+ EG_PA_CL_GB_HORZ_CLIP_ADJ = 0x28C14, // SAME
+ EG_PA_CL_GB_HORZ_DISC_ADJ = 0x28C18, // SAME
+ EG_PA_SC_AA_SAMPLE_LOCS_0 = 0x28C1C, //
+ EG_PA_SC_AA_SAMPLE_LOCS_1 = 0x28C20, //
+ EG_PA_SC_AA_SAMPLE_LOCS_2 = 0x28C24, //
+ EG_PA_SC_AA_SAMPLE_LOCS_3 = 0x28C28, //
+ EG_PA_SC_AA_SAMPLE_LOCS_4 = 0x28C2C, //
+ EG_PA_SC_AA_SAMPLE_LOCS_5 = 0x28C30, //
+ EG_PA_SC_AA_SAMPLE_LOCS_6 = 0x28C34, //
+ EG_PA_SC_AA_SAMPLE_LOCS_7 = 0x28C38, //
+ EG_PA_SC_AA_MASK = 0x28C3C, // SAME 0x28C48
+
+/* Registers from VGT block: */
+ EG_VGT_INDEX_TYPE = 0x895C, //? config space
+ EG_VGT_PRIMITIVE_TYPE = 0x8958, //? config space
+
+ EG_VGT_MAX_VTX_INDX = 0x28400, // SAME
+ EG_VGT_MIN_VTX_INDX = 0x28404, // SAME
+ EG_VGT_INDX_OFFSET = 0x28408, // SAME
+ EG_VGT_MULTI_PRIM_IB_RESET_INDX = 0x2840C, // SAME
+ EG_CS_COPY_STATE = 0x287CC, //
+ EG_GFX_COPY_STATE = 0x287D0, // SAME
+ EG_VGT_DMA_BASE_HI = 0x287E4, // SAME
+ EG_VGT_DMA_BASE = 0x287E8, // SAME
+ EG_VGT_DRAW_INITIATOR = 0x287F0, // SAME
+ EG_VGT_IMMED_DATA = 0x287F4, // SAME
+ EG_VGT_EVENT_ADDRESS_REG = 0x287F8, // SAME
+ EG_VGT_OUTPUT_PATH_CNTL = 0x28A10, // DIFF
+ EG_VGT_HOS_CNTL = 0x28A14, // SAME
+ EG_VGT_HOS_MAX_TESS_LEVEL = 0x28A18, // SAME
+ EG_VGT_HOS_MIN_TESS_LEVEL = 0x28A1C, // SAME
+ EG_VGT_HOS_REUSE_DEPTH = 0x28A20, // SAME
+ EG_VGT_GROUP_PRIM_TYPE = 0x28A24, // SAME
+ EG_VGT_GROUP_FIRST_DECR = 0x28A28, // SAME
+ EG_VGT_GROUP_DECR = 0x28A2C, // SAME
+ EG_VGT_GROUP_VECT_0_CNTL = 0x28A30, // SAME
+ EG_VGT_GROUP_VECT_1_CNTL = 0x28A34, // SAME
+ EG_VGT_GROUP_VECT_0_FMT_CNTL = 0x28A38, // SAME
+ EG_VGT_GROUP_VECT_1_FMT_CNTL = 0x28A3C, // SAME
+ EG_VGT_GS_MODE = 0x28A40, // DIFF
+ EG_VGT_ENHANCE = 0x28A50, // DIFF
+ EG_VGT_GS_PER_ES = 0x28A54, // DIFF 0x88C8
+ EG_VGT_ES_PER_GS = 0x28A58, // DIFF 0x88CC
+ EG_VGT_GS_PER_VS = 0x28A5C, // SAME 0x88E8
+ EG_VGT_GS_OUT_PRIM_TYPE = 0x28A6C, // SAME
+ EG_VGT_DMA_SIZE = 0x28A74, // SAME
+ EG_VGT_DMA_MAX_SIZE = 0x28A78, // SAME
+ EG_VGT_DMA_INDEX_TYPE = 0x28A7C, // SAME
+ EG_VGT_PRIMITIVEID_EN = 0x28A84, // SAME
+ EG_VGT_DMA_NUM_INSTANCES = 0x28A88, // SAME
+ EG_VGT_EVENT_INITIATOR = 0x28A90, // SAME
+ EG_VGT_MULTI_PRIM_IB_RESET_EN = 0x28A94, // SAME
+ EG_VGT_INSTANCE_STEP_RATE_0 = 0x28AA0, // SAME
+ EG_VGT_INSTANCE_STEP_RATE_1 = 0x28AA4, // SAME
+ EG_VGT_REUSE_OFF = 0x28AB4, // SAME
+ EG_VGT_VTX_CNT_EN = 0x28AB8, // SAME
+ EG_VGT_STRMOUT_BUFFER_SIZE_0 = 0x28AD0, // SAME
+ EG_VGT_STRMOUT_VTX_STRIDE_0 = 0x28AD4, // SAME
+ EG_VGT_STRMOUT_BUFFER_BASE_0 = 0x28AD8, // SAME
+ EG_VGT_STRMOUT_BUFFER_OFFSET_0 = 0x28ADC, // SAME
+ EG_VGT_STRMOUT_BUFFER_SIZE_1 = 0x28AE0, // SAME
+ EG_VGT_STRMOUT_VTX_STRIDE_1 = 0x28AE4, // SAME
+ EG_VGT_STRMOUT_BUFFER_BASE_1 = 0x28AE8, // SAME
+ EG_VGT_STRMOUT_BUFFER_OFFSET_1 = 0x28AEC, // SAME
+ EG_VGT_STRMOUT_BUFFER_SIZE_2 = 0x28AF0, // SAME
+ EG_VGT_STRMOUT_VTX_STRIDE_2 = 0x28AF4, // SAME
+ EG_VGT_STRMOUT_BUFFER_BASE_2 = 0x28AF8, // SAME
+ EG_VGT_STRMOUT_BUFFER_OFFSET_2 = 0x28AFC, // SAME
+ EG_VGT_STRMOUT_BUFFER_SIZE_3 = 0x28B00, // SAME
+ EG_VGT_STRMOUT_VTX_STRIDE_3 = 0x28B04, // SAME
+ EG_VGT_STRMOUT_BUFFER_BASE_3 = 0x28B08, // SAME
+ EG_VGT_STRMOUT_BUFFER_OFFSET_3 = 0x28B0C, // SAME
+ EG_VGT_STRMOUT_BASE_OFFSET_0 = 0x28B10, // SAME
+ EG_VGT_STRMOUT_BASE_OFFSET_1 = 0x28B14, // SAME
+ EG_VGT_STRMOUT_BASE_OFFSET_2 = 0x28B18, // SAME
+ EG_VGT_STRMOUT_BASE_OFFSET_3 = 0x28B1C, // SAME
+ EG_VGT_STRMOUT_DRAW_OPAQUE_OFFSET = 0x28B28, // SAME
+ EG_VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE = 0x28B2C, // SAME
+ EG_VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE = 0x28B30, // DIFF
+ EG_VGT_GS_MAX_VERT_OUT = 0x28B38, // SAME
+ EG_VGT_STRMOUT_BASE_OFFSET_HI_0 = 0x28B44, // SAME
+ EG_VGT_STRMOUT_BASE_OFFSET_HI_1 = 0x28B48, // SAME
+ EG_VGT_STRMOUT_BASE_OFFSET_HI_2 = 0x28B4C, // SAME
+ EG_VGT_STRMOUT_BASE_OFFSET_HI_3 = 0x28B50, // SAME
+ EG_VGT_SHADER_STAGES_EN = 0x28B54, //
+ EG_VGT_LS_HS_CONFIG = 0x28B58, //
+ EG_VGT_LS_SIZE = 0x28B5C, //
+ EG_VGT_HS_SIZE = 0x28B60, //
+ EG_VGT_LS_HS_ALLOC = 0x28B64, //
+ EG_VGT_HS_PATCH_CONST = 0x28B68, //
+ EG_VGT_TF_PARAM = 0x28B6C, //
+ EG_VGT_DISPATCH_INITIATOR = 0x28B74, //
+ EG_VGT_GS_INSTANCE_CNT = 0x28B90, //
+ EG_VGT_STRMOUT_CONFIG = 0x28B94, //
+ EG_VGT_STRMOUT_BUFFER_CONFIG = 0x28B98, //
+ EG_VGT_VERTEX_REUSE_BLOCK_CNTL = 0x28C58, // SAME
+ EG_VGT_OUT_DEALLOC_CNTL = 0x28C5C, // SAME
+
+/* Registers from TP block: */
+ EG_GDS_ADDR_BASE = 0x28720, //
+ EG_GDS_ADDR_SIZE = 0x28724, //
+ EG_GDS_ORDERED_WAVE_PER_SE = 0x28728, //
+ EG_GDS_APPEND_CONSUME_UAV0 = 0x2872C, //
+ EG_GDS_APPEND_CONSUME_UAV1 = 0x28730, //
+ EG_GDS_APPEND_CONSUME_UAV2 = 0x28734, //
+ EG_GDS_APPEND_CONSUME_UAV3 = 0x28738, //
+ EG_GDS_APPEND_CONSUME_UAV4 = 0x2873C, //
+ EG_GDS_APPEND_CONSUME_UAV5 = 0x28740, //
+ EG_GDS_APPEND_CONSUME_UAV6 = 0x28744, //
+ EG_GDS_APPEND_CONSUME_UAV7 = 0x28748, //
+ EG_GDS_APPEND_CONSUME_UAV8 = 0x2874C, //
+ EG_GDS_APPEND_CONSUME_UAV9 = 0x28750, //
+ EG_GDS_APPEND_CONSUME_UAV10 = 0x28754, //
+ EG_GDS_APPEND_CONSUME_UAV11 = 0x28758, //
+
+/* Registers from SQ block: */
+ EG_SQ_LOOP_CONST_0 = 0x3A200, // 0x3E200
+ EG_SQ_ALU_CONST_BUFFER_SIZE_VS_0 = 0x28180, // ?
+ EG_SQ_VTX_SEMANTIC_0 = 0x28380, // SAME
+ EG_SQ_VTX_SEMANTIC_1 = 0x28384, // SAME
+ EG_SQ_VTX_SEMANTIC_2 = 0x28388, // SAME
+ EG_SQ_VTX_SEMANTIC_3 = 0x2838C, // SAME
+ EG_SQ_VTX_SEMANTIC_4 = 0x28390, // SAME
+ EG_SQ_VTX_SEMANTIC_5 = 0x28394, // SAME
+ EG_SQ_VTX_SEMANTIC_6 = 0x28398, // SAME
+ EG_SQ_VTX_SEMANTIC_7 = 0x2839C, // SAME
+ EG_SQ_VTX_SEMANTIC_8 = 0x283A0, // SAME
+ EG_SQ_VTX_SEMANTIC_9 = 0x283A4, // SAME
+ EG_SQ_VTX_SEMANTIC_10 = 0x283A8, // SAME
+ EG_SQ_VTX_SEMANTIC_11 = 0x283AC, // SAME
+ EG_SQ_VTX_SEMANTIC_12 = 0x283B0, // SAME
+ EG_SQ_VTX_SEMANTIC_13 = 0x283B4, // SAME
+ EG_SQ_VTX_SEMANTIC_14 = 0x283B8, // SAME
+ EG_SQ_VTX_SEMANTIC_15 = 0x283BC, // SAME
+ EG_SQ_VTX_SEMANTIC_16 = 0x283C0, // SAME
+ EG_SQ_VTX_SEMANTIC_17 = 0x283C4, // SAME
+ EG_SQ_VTX_SEMANTIC_18 = 0x283C8, // SAME
+ EG_SQ_VTX_SEMANTIC_19 = 0x283CC, // SAME
+ EG_SQ_VTX_SEMANTIC_20 = 0x283D0, // SAME
+ EG_SQ_VTX_SEMANTIC_21 = 0x283D4, // SAME
+ EG_SQ_VTX_SEMANTIC_22 = 0x283D8, // SAME
+ EG_SQ_VTX_SEMANTIC_23 = 0x283DC, // SAME
+ EG_SQ_VTX_SEMANTIC_24 = 0x283E0, // SAME
+ EG_SQ_VTX_SEMANTIC_25 = 0x283E4, // SAME
+ EG_SQ_VTX_SEMANTIC_26 = 0x283E8, // SAME
+ EG_SQ_VTX_SEMANTIC_27 = 0x283EC, // SAME
+ EG_SQ_VTX_SEMANTIC_28 = 0x283F0, // SAME
+ EG_SQ_VTX_SEMANTIC_29 = 0x283F4, // SAME
+ EG_SQ_VTX_SEMANTIC_30 = 0x283F8, // SAME
+ EG_SQ_VTX_SEMANTIC_31 = 0x283FC, // SAME
+ EG_SQ_LSTMP_RING_ITEMSIZE = 0x28830, //
+ EG_SQ_HSTMP_RING_ITEMSIZE = 0x28834, //
+ EG_SQ_DYN_GPR_RESOURCE_LIMIT_1 = 0x28838, //
+ EG_SQ_PGM_START_PS = 0x28840, // SAME
+ EG_SQ_PGM_RESOURCES_PS = 0x28844, // DIFF 0x28850
+ EG_SQ_PGM_RESOURCES_2_PS = 0x28848, //
+ EG_SQ_PGM_EXPORTS_PS = 0x2884C, // SAME 0x28854
+ EG_SQ_PGM_START_VS = 0x2885C, // SAME 0x28858
+ EG_SQ_PGM_RESOURCES_VS = 0x28860, // DIFF 0x28868
+ EG_SQ_PGM_RESOURCES_2_VS = 0x28864, //
+ EG_SQ_PGM_START_GS = 0x28874, // SAME 0x2886C
+ EG_SQ_PGM_RESOURCES_GS = 0x28878, // DIFF 0x2887C
+ EG_SQ_PGM_RESOURCES_2_GS = 0x2887C, //
+ EG_SQ_PGM_START_ES = 0x2888C, // SAME 0x28880
+ EG_SQ_PGM_RESOURCES_ES = 0x28890, // DIFF
+ EG_SQ_PGM_RESOURCES_2_ES = 0x28894, //
+ EG_SQ_PGM_START_FS = 0x288A4, // SAME 0x28894
+ EG_SQ_PGM_RESOURCES_FS = 0x288A8, // DIFF 0x288A4
+ EG_SQ_PGM_START_HS = 0x288B8, //
+ EG_SQ_PGM_RESOURCES_HS = 0x288BC, //
+ EG_SQ_PGM_RESOURCES_2_HS = 0x288C0, //
+ EG_SQ_PGM_START_LS = 0x288D0, //
+ EG_SQ_PGM_RESOURCES_LS = 0x288D4, //
+ EG_SQ_PGM_RESOURCES_2_LS = 0x288D8, //
+ EG_SQ_THREAD_TRACE_USERDATA = 0x288DC, //
+ EG_SQ_LDS_ALLOC = 0x288E8, //
+ EG_SQ_LDS_ALLOC_PS = 0x288EC, //
+ EG_SQ_VTX_SEMANTIC_CLEAR = 0x288F0, // SAME 0x288E0
+ EG_SQ_THREAD_TRACE_CTRL = 0x288F8, //
+ EG_SQ_ESGS_RING_ITEMSIZE = 0x28900, // SAME 0x288A8
+ EG_SQ_GSVS_RING_ITEMSIZE = 0x28904, // SAME 0x288AC
+ EG_SQ_ESTMP_RING_ITEMSIZE = 0x28908, // SAME 0x288B0
+ EG_SQ_GSTMP_RING_ITEMSIZE = 0x2890C, // SAME 0x288B4
+ EG_SQ_VSTMP_RING_ITEMSIZE = 0x28910, // SAME 0x288B8
+ EG_SQ_PSTMP_RING_ITEMSIZE = 0x28914, // SAME 0x288BC
+ EG_SQ_GS_VERT_ITEMSIZE = 0x2891C, // SAME 0x288C8
+ EG_SQ_GS_VERT_ITEMSIZE_1 = 0x28920, //
+ EG_SQ_GS_VERT_ITEMSIZE_2 = 0x28924, //
+ EG_SQ_GS_VERT_ITEMSIZE_3 = 0x28928, //
+ EG_SQ_GSVS_RING_OFFSET_1 = 0x2892C, //
+ EG_SQ_GSVS_RING_OFFSET_2 = 0x28930, //
+ EG_SQ_GSVS_RING_OFFSET_3 = 0x28934, //
+ EG_SQ_ALU_CONST_CACHE_PS_0 = 0x28940, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_1 = 0x28944, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_2 = 0x28948, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_3 = 0x2894C, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_4 = 0x28950, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_5 = 0x28954, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_6 = 0x28958, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_7 = 0x2895C, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_8 = 0x28960, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_9 = 0x28964, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_10 = 0x28968, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_11 = 0x2896C, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_12 = 0x28970, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_13 = 0x28974, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_14 = 0x28978, // SAME
+ EG_SQ_ALU_CONST_CACHE_PS_15 = 0x2897C, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_0 = 0x28980, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_1 = 0x28984, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_2 = 0x28988, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_3 = 0x2898C, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_4 = 0x28990, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_5 = 0x28994, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_6 = 0x28998, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_7 = 0x2899C, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_8 = 0x289A0, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_9 = 0x289A4, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_10 = 0x289A8, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_11 = 0x289AC, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_12 = 0x289B0, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_13 = 0x289B4, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_14 = 0x289B8, // SAME
+ EG_SQ_ALU_CONST_CACHE_VS_15 = 0x289BC, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_0 = 0x289C0, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_1 = 0x289C4, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_2 = 0x289C8, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_3 = 0x289CC, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_4 = 0x289D0, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_5 = 0x289D4, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_6 = 0x289D8, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_7 = 0x289DC, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_8 = 0x289E0, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_9 = 0x289E4, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_10 = 0x289E8, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_11 = 0x289EC, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_12 = 0x289F0, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_13 = 0x289F4, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_14 = 0x289F8, // SAME
+ EG_SQ_ALU_CONST_CACHE_GS_15 = 0x289FC, // SAME
+ EG_SQ_ALU_CONST_CACHE_HS_0 = 0x28F00, //
+ EG_SQ_ALU_CONST_CACHE_HS_1 = 0x28F04, //
+ EG_SQ_ALU_CONST_CACHE_HS_2 = 0x28F08, //
+ EG_SQ_ALU_CONST_CACHE_HS_3 = 0x28F0C, //
+ EG_SQ_ALU_CONST_CACHE_HS_4 = 0x28F10, //
+ EG_SQ_ALU_CONST_CACHE_HS_5 = 0x28F14, //
+ EG_SQ_ALU_CONST_CACHE_HS_6 = 0x28F18, //
+ EG_SQ_ALU_CONST_CACHE_HS_7 = 0x28F1C, //
+ EG_SQ_ALU_CONST_CACHE_HS_8 = 0x28F20, //
+ EG_SQ_ALU_CONST_CACHE_HS_9 = 0x28F24, //
+ EG_SQ_ALU_CONST_CACHE_HS_10 = 0x28F28, //
+ EG_SQ_ALU_CONST_CACHE_HS_11 = 0x28F2C, //
+ EG_SQ_ALU_CONST_CACHE_HS_12 = 0x28F30, //
+ EG_SQ_ALU_CONST_CACHE_HS_13 = 0x28F34, //
+ EG_SQ_ALU_CONST_CACHE_HS_14 = 0x28F38, //
+ EG_SQ_ALU_CONST_CACHE_HS_15 = 0x28F3C, //
+ EG_SQ_ALU_CONST_CACHE_LS_0 = 0x28F40, //
+ EG_SQ_ALU_CONST_CACHE_LS_1 = 0x28F44, //
+ EG_SQ_ALU_CONST_CACHE_LS_2 = 0x28F48, //
+ EG_SQ_ALU_CONST_CACHE_LS_3 = 0x28F4C, //
+ EG_SQ_ALU_CONST_CACHE_LS_4 = 0x28F50, //
+ EG_SQ_ALU_CONST_CACHE_LS_5 = 0x28F54, //
+ EG_SQ_ALU_CONST_CACHE_LS_6 = 0x28F58, //
+ EG_SQ_ALU_CONST_CACHE_LS_7 = 0x28F5C, //
+ EG_SQ_ALU_CONST_CACHE_LS_8 = 0x28F60, //
+ EG_SQ_ALU_CONST_CACHE_LS_9 = 0x28F64, //
+ EG_SQ_ALU_CONST_CACHE_LS_10 = 0x28F68, //
+ EG_SQ_ALU_CONST_CACHE_LS_11 = 0x28F6C, //
+ EG_SQ_ALU_CONST_CACHE_LS_12 = 0x28F70, //
+ EG_SQ_ALU_CONST_CACHE_LS_13 = 0x28F74, //
+ EG_SQ_ALU_CONST_CACHE_LS_14 = 0x28F78, //
+ EG_SQ_ALU_CONST_CACHE_LS_15 = 0x28F7C, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_PS_0 = 0x28140,
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_0 = 0x28F80, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_1 = 0x28F84, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_2 = 0x28F88, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_3 = 0x28F8C, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_4 = 0x28F90, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_5 = 0x28F94, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_6 = 0x28F98, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_7 = 0x28F9C, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_8 = 0x28FA0, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_9 = 0x28FA4, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_10 = 0x28FA8, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_11 = 0x28FAC, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_12 = 0x28FB0, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_13 = 0x28FB4, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_14 = 0x28FB8, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_HS_15 = 0x28FBC, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_0 = 0x28FC0, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_1 = 0x28FC4, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_2 = 0x28FC8, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_3 = 0x28FCC, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_4 = 0x28FD0, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_5 = 0x28FD4, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_6 = 0x28FD8, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_7 = 0x28FDC, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_8 = 0x28FE0, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_9 = 0x28FE4, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_10 = 0x28FE8, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_11 = 0x28FEC, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_12 = 0x28FF0, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_13 = 0x28FF4, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_14 = 0x28FF8, //
+ EG_SQ_ALU_CONST_BUFFER_SIZE_LS_15 = 0x28FFC, //
+
+/* Registers from SPI block: */
+ EG_SPI_VS_OUT_ID_0 = 0x2861C, // SAME 0x28614
+ EG_SPI_VS_OUT_ID_1 = 0x28620, // SAME 0x28618
+ EG_SPI_VS_OUT_ID_2 = 0x28624, // SAME 0x2861C
+ EG_SPI_VS_OUT_ID_3 = 0x28628, // SAME 0x28620
+ EG_SPI_VS_OUT_ID_4 = 0x2862C, // SAME 0x28624
+ EG_SPI_VS_OUT_ID_5 = 0x28630, // SAME 0x28628
+ EG_SPI_VS_OUT_ID_6 = 0x28634, // SAME 0x2862C
+ EG_SPI_VS_OUT_ID_7 = 0x28638, // SAME 0x28630
+ EG_SPI_VS_OUT_ID_8 = 0x2863C, // SAME 0x28634
+ EG_SPI_VS_OUT_ID_9 = 0x28640, // SAME 0x28638
+ EG_SPI_PS_INPUT_CNTL_0 = 0x28644, // SAME
+ EG_SPI_PS_INPUT_CNTL_1 = 0x28648, // SAME
+ EG_SPI_PS_INPUT_CNTL_2 = 0x2864C, // SAME
+ EG_SPI_PS_INPUT_CNTL_3 = 0x28650, // SAME
+ EG_SPI_PS_INPUT_CNTL_4 = 0x28654, // SAME
+ EG_SPI_PS_INPUT_CNTL_5 = 0x28658, // SAME
+ EG_SPI_PS_INPUT_CNTL_6 = 0x2865C, // SAME
+ EG_SPI_PS_INPUT_CNTL_7 = 0x28660, // SAME
+ EG_SPI_PS_INPUT_CNTL_8 = 0x28664, // SAME
+ EG_SPI_PS_INPUT_CNTL_9 = 0x28668, // SAME
+ EG_SPI_PS_INPUT_CNTL_10 = 0x2866C, // SAME
+ EG_SPI_PS_INPUT_CNTL_11 = 0x28670, // SAME
+ EG_SPI_PS_INPUT_CNTL_12 = 0x28674, // SAME
+ EG_SPI_PS_INPUT_CNTL_13 = 0x28678, // SAME
+ EG_SPI_PS_INPUT_CNTL_14 = 0x2867C, // SAME
+ EG_SPI_PS_INPUT_CNTL_15 = 0x28680, // SAME
+ EG_SPI_PS_INPUT_CNTL_16 = 0x28684, // SAME
+ EG_SPI_PS_INPUT_CNTL_17 = 0x28688, // SAME
+ EG_SPI_PS_INPUT_CNTL_18 = 0x2868C, // SAME
+ EG_SPI_PS_INPUT_CNTL_19 = 0x28690, // SAME
+ EG_SPI_PS_INPUT_CNTL_20 = 0x28694, // SAME
+ EG_SPI_PS_INPUT_CNTL_21 = 0x28698, // SAME
+ EG_SPI_PS_INPUT_CNTL_22 = 0x2869C, // SAME
+ EG_SPI_PS_INPUT_CNTL_23 = 0x286A0, // SAME
+ EG_SPI_PS_INPUT_CNTL_24 = 0x286A4, // SAME
+ EG_SPI_PS_INPUT_CNTL_25 = 0x286A8, // SAME
+ EG_SPI_PS_INPUT_CNTL_26 = 0x286AC, // SAME
+ EG_SPI_PS_INPUT_CNTL_27 = 0x286B0, // SAME
+ EG_SPI_PS_INPUT_CNTL_28 = 0x286B4, // SAME
+ EG_SPI_PS_INPUT_CNTL_29 = 0x286B8, // SAME
+ EG_SPI_PS_INPUT_CNTL_30 = 0x286BC, // SAME
+ EG_SPI_PS_INPUT_CNTL_31 = 0x286C0, // SAME
+ EG_SPI_VS_OUT_CONFIG = 0x286C4, // SAME
+ EG_SPI_THREAD_GROUPING = 0x286C8, // DIFF
+ EG_SPI_PS_IN_CONTROL_0 = 0x286CC, // SAME
+ EG_SPI_PS_IN_CONTROL_1 = 0x286D0, // SAME
+ EG_SPI_INTERP_CONTROL_0 = 0x286D4, // SAME
+ EG_SPI_INPUT_Z = 0x286D8, // SAME
+ EG_SPI_FOG_CNTL = 0x286DC, // SAME
+ EG_SPI_BARYC_CNTL = 0x286E0, //
+ EG_SPI_PS_IN_CONTROL_2 = 0x286E4, //
+ EG_SPI_COMPUTE_INPUT_CNTL = 0x286E8, //
+ EG_SPI_COMPUTE_NUM_THREAD_X = 0x286EC, //
+ EG_SPI_COMPUTE_NUM_THREAD_Y = 0x286F0, //
+ EG_SPI_COMPUTE_NUM_THREAD_Z = 0x286F4, //
+
+/* Registers from SX block: */
+ EG_SX_MISC = 0x28350, // SAME
+ EG_SX_SURFACE_SYNC = 0x28354, // DIFF
+ EG_SX_ALPHA_TEST_CONTROL = 0x28410, // SAME
+ EG_SX_ALPHA_REF = 0x28438, // SAME
+
+/* Registers from DB block: */
+ EG_DB_RENDER_CONTROL = 0x28000, // DIFF 0x28D0C
+ EG_DB_COUNT_CONTROL = 0x28004, //
+ EG_DB_DEPTH_VIEW = 0x28008, // DIFF 0x28004
+ EG_DB_RENDER_OVERRIDE = 0x2800C, // DIFF 0x28D10
+ EG_DB_RENDER_OVERRIDE2 = 0x28010, //
+ EG_DB_HTILE_DATA_BASE = 0x28014, // SAME
+
+ EG_DB_STENCIL_CLEAR = 0x28028, // SAME
+ EG_DB_DEPTH_CLEAR = 0x2802C, // SAME
+
+ EG_DB_Z_INFO = 0x28040, //
+ EG_DB_STENCIL_INFO = 0x28044, //
+ EG_DB_Z_READ_BASE = 0x28048, //
+ EG_DB_STENCIL_READ_BASE = 0x2804C, //
+ EG_DB_Z_WRITE_BASE = 0x28050, //
+ EG_DB_STENCIL_WRITE_BASE = 0x28054, //
+ EG_DB_DEPTH_SIZE = 0x28058, // DIFF 0x28000
+ EG_DB_DEPTH_SLICE = 0x2805C, //
+
+ EG_DB_STENCILREFMASK = 0x28430, // SAME
+ EG_DB_STENCILREFMASK_BF = 0x28434, // SAME
+ EG_DB_DEPTH_CONTROL = 0x28800, // SAME
+ EG_DB_SHADER_CONTROL = 0x2880C, // DIFF
+ EG_DB_HTILE_SURFACE = 0x28ABC, // SAME 0x28D24
+ EG_DB_SRESULTS_COMPARE_STATE0 = 0x28AC0, // SAME 0x28D28
+ EG_DB_SRESULTS_COMPARE_STATE1 = 0x28AC4, // SAME 0x28D2C
+ EG_DB_PRELOAD_CONTROL = 0x28AC8, // SAME 0x28D30
+ EG_DB_ALPHA_TO_MASK = 0x28B70, // SAME 0x28D44
+
+/* Registers from CB block: */
+ EG_CB_TARGET_MASK = 0x28238, // SAME
+ EG_CB_SHADER_MASK = 0x2823C, // SAME
+ EG_CB_BLEND_RED = 0x28414, // SAME
+ EG_CB_BLEND_GREEN = 0x28418, // SAME
+ EG_CB_BLEND_BLUE = 0x2841C, // SAME
+ EG_CB_BLEND_ALPHA = 0x28420, // SAME
+ EG_CB_BLEND0_CONTROL = 0x28780, // DIFF
+ EG_CB_BLEND1_CONTROL = 0x28784, // DIFF
+ EG_CB_BLEND2_CONTROL = 0x28788, // DIFF
+ EG_CB_BLEND3_CONTROL = 0x2878C, // DIFF
+ EG_CB_BLEND4_CONTROL = 0x28790, // DIFF
+ EG_CB_BLEND5_CONTROL = 0x28794, // DIFF
+ EG_CB_BLEND6_CONTROL = 0x28798, // DIFF
+ EG_CB_BLEND7_CONTROL = 0x2879C, // DIFF
+ EG_CB_COLOR_CONTROL = 0x28808, // DIFF
+ EG_CB_IMMED0_BASE = 0x28B9C, //
+ EG_CB_IMMED1_BASE = 0x28BA0, //
+ EG_CB_IMMED2_BASE = 0x28BA4, //
+ EG_CB_IMMED3_BASE = 0x28BA8, //
+ EG_CB_IMMED4_BASE = 0x28BAC, //
+ EG_CB_IMMED5_BASE = 0x28BB0, //
+ EG_CB_IMMED6_BASE = 0x28BB4, //
+ EG_CB_IMMED7_BASE = 0x28BB8, //
+ EG_CB_IMMED8_BASE = 0x28BBC, //
+ EG_CB_IMMED9_BASE = 0x28BC0, //
+ EG_CB_IMMED10_BASE = 0x28BC4, //
+ EG_CB_IMMED11_BASE = 0x28BC8, //
+ EG_CB_CLRCMP_CONTROL = 0x28C40, // SAME 0x28C30
+ EG_CB_CLRCMP_SRC = 0x28C44, // SAME 0x28C34
+ EG_CB_CLRCMP_DST = 0x28C48, // SAME 0x28C38
+ EG_CB_CLRCMP_MSK = 0x28C4C, // SAME 0x28C3C
+ EG_CB_COLOR0_BASE = 0x28C60, // SAME 0x28040
+ EG_CB_COLOR0_PITCH = 0x28C64, //
+ EG_CB_COLOR0_SLICE = 0x28C68, //
+ EG_CB_COLOR0_VIEW = 0x28C6C, // SAME 0x28080
+ EG_CB_COLOR0_INFO = 0x28C70, // DIFF 0x280A0
+ EG_CB_COLOR0_ATTRIB = 0x28C74, //
+ EG_CB_COLOR0_DIM = 0x28C78, //
+ EG_CB_COLOR0_CMASK = 0x28C7C, //
+ EG_CB_COLOR0_CMASK_SLICE = 0x28C80, //
+ EG_CB_COLOR0_FMASK = 0x28C84, //
+ EG_CB_COLOR0_FMASK_SLICE = 0x28C88, //
+ EG_CB_COLOR0_CLEAR_WORD0 = 0x28C8C, //
+ EG_CB_COLOR0_CLEAR_WORD1 = 0x28C90, //
+ EG_CB_COLOR0_CLEAR_WORD2 = 0x28C94, //
+ EG_CB_COLOR0_CLEAR_WORD3 = 0x28C98, //
+ EG_CB_COLOR1_BASE = 0x28C9C, // SAME 0x28044
+ EG_CB_COLOR1_PITCH = 0x28CA0, //
+ EG_CB_COLOR1_SLICE = 0x28CA4, //
+ EG_CB_COLOR1_VIEW = 0x28CA8, // SAME 0x28084
+ EG_CB_COLOR1_INFO = 0x28CAC, // DIFF 0x280A4
+ EG_CB_COLOR1_ATTRIB = 0x28CB0, //
+ EG_CB_COLOR1_DIM = 0x28CB4, //
+ EG_CB_COLOR1_CMASK = 0x28CB8, //
+ EG_CB_COLOR1_CMASK_SLICE = 0x28CBC, //
+ EG_CB_COLOR1_FMASK = 0x28CC0, //
+ EG_CB_COLOR1_FMASK_SLICE = 0x28CC4, //
+ EG_CB_COLOR1_CLEAR_WORD0 = 0x28CC8, //
+ EG_CB_COLOR1_CLEAR_WORD1 = 0x28CCC, //
+ EG_CB_COLOR1_CLEAR_WORD2 = 0x28CD0, //
+ EG_CB_COLOR1_CLEAR_WORD3 = 0x28CD4, //
+ EG_CB_COLOR2_BASE = 0x28CD8, // SAME 0x28048
+ EG_CB_COLOR2_PITCH = 0x28CDC, //
+ EG_CB_COLOR2_SLICE = 0x28CE0, //
+ EG_CB_COLOR2_VIEW = 0x28CE4, // SAME 0x28088
+ EG_CB_COLOR2_INFO = 0x28CE8, // DIFF 0x280A8
+ EG_CB_COLOR2_ATTRIB = 0x28CEC, //
+ EG_CB_COLOR2_DIM = 0x28CF0, //
+ EG_CB_COLOR2_CMASK = 0x28CF4, //
+ EG_CB_COLOR2_CMASK_SLICE = 0x28CF8, //
+ EG_CB_COLOR2_FMASK = 0x28CFC, //
+ EG_CB_COLOR2_FMASK_SLICE = 0x28D00, //
+ EG_CB_COLOR2_CLEAR_WORD0 = 0x28D04, //
+ EG_CB_COLOR2_CLEAR_WORD1 = 0x28D08, //
+ EG_CB_COLOR2_CLEAR_WORD2 = 0x28D0C, //
+ EG_CB_COLOR2_CLEAR_WORD3 = 0x28D10, //
+ EG_CB_COLOR3_BASE = 0x28D14, // SAME 0x2804C
+ EG_CB_COLOR3_PITCH = 0x28D18, //
+ EG_CB_COLOR3_SLICE = 0x28D1C, //
+ EG_CB_COLOR3_VIEW = 0x28D20, // SAME 0x2808C
+ EG_CB_COLOR3_INFO = 0x28D24, // DIFF 0x280AC
+ EG_CB_COLOR3_ATTRIB = 0x28D28, //
+ EG_CB_COLOR3_DIM = 0x28D2C, //
+ EG_CB_COLOR3_CMASK = 0x28D30, //
+ EG_CB_COLOR3_CMASK_SLICE = 0x28D34, //
+ EG_CB_COLOR3_FMASK = 0x28D38, //
+ EG_CB_COLOR3_FMASK_SLICE = 0x28D3C, //
+ EG_CB_COLOR3_CLEAR_WORD0 = 0x28D40, //
+ EG_CB_COLOR3_CLEAR_WORD1 = 0x28D44, //
+ EG_CB_COLOR3_CLEAR_WORD2 = 0x28D48, //
+ EG_CB_COLOR3_CLEAR_WORD3 = 0x28D4C, //
+ EG_CB_COLOR4_BASE = 0x28D50, // SAME 0x28050
+ EG_CB_COLOR4_PITCH = 0x28D54, //
+ EG_CB_COLOR4_SLICE = 0x28D58, //
+ EG_CB_COLOR4_VIEW = 0x28D5C, // SAME 0x28090
+ EG_CB_COLOR4_INFO = 0x28D60, // DIFF 0x280B0
+ EG_CB_COLOR4_ATTRIB = 0x28D64, //
+ EG_CB_COLOR4_DIM = 0x28D68, //
+ EG_CB_COLOR4_CMASK = 0x28D6C, //
+ EG_CB_COLOR4_CMASK_SLICE = 0x28D70, //
+ EG_CB_COLOR4_FMASK = 0x28D74, //
+ EG_CB_COLOR4_FMASK_SLICE = 0x28D78, //
+ EG_CB_COLOR4_CLEAR_WORD0 = 0x28D7C, //
+ EG_CB_COLOR4_CLEAR_WORD1 = 0x28D80, //
+ EG_CB_COLOR4_CLEAR_WORD2 = 0x28D84, //
+ EG_CB_COLOR4_CLEAR_WORD3 = 0x28D88, //
+ EG_CB_COLOR5_BASE = 0x28D8C, // SAME 0x28054
+ EG_CB_COLOR5_PITCH = 0x28D90, //
+ EG_CB_COLOR5_SLICE = 0x28D94, //
+ EG_CB_COLOR5_VIEW = 0x28D98, // SAME 0x28094
+ EG_CB_COLOR5_INFO = 0x28D9C, // DIFF 0x280B4
+ EG_CB_COLOR5_ATTRIB = 0x28DA0, //
+ EG_CB_COLOR5_DIM = 0x28DA4, //
+ EG_CB_COLOR5_CMASK = 0x28DA8, //
+ EG_CB_COLOR5_CMASK_SLICE = 0x28DAC, //
+ EG_CB_COLOR5_FMASK = 0x28DB0, //
+ EG_CB_COLOR5_FMASK_SLICE = 0x28DB4, //
+ EG_CB_COLOR5_CLEAR_WORD0 = 0x28DB8, //
+ EG_CB_COLOR5_CLEAR_WORD1 = 0x28DBC, //
+ EG_CB_COLOR5_CLEAR_WORD2 = 0x28DC0, //
+ EG_CB_COLOR5_CLEAR_WORD3 = 0x28DC4, //
+ EG_CB_COLOR6_BASE = 0x28DC8, // SAME 0x28058
+ EG_CB_COLOR6_PITCH = 0x28DCC, //
+ EG_CB_COLOR6_SLICE = 0x28DD0, //
+ EG_CB_COLOR6_VIEW = 0x28DD4, // SAME 0x28098
+ EG_CB_COLOR6_INFO = 0x28DD8, // DIFF 0x280B8
+ EG_CB_COLOR6_ATTRIB = 0x28DDC, //
+ EG_CB_COLOR6_DIM = 0x28DE0, //
+ EG_CB_COLOR6_CMASK = 0x28DE4, //
+ EG_CB_COLOR6_CMASK_SLICE = 0x28DE8, //
+ EG_CB_COLOR6_FMASK = 0x28DEC, //
+ EG_CB_COLOR6_FMASK_SLICE = 0x28DF0, //
+ EG_CB_COLOR6_CLEAR_WORD0 = 0x28DF4, //
+ EG_CB_COLOR6_CLEAR_WORD1 = 0x28DF8, //
+ EG_CB_COLOR6_CLEAR_WORD2 = 0x28DFC, //
+ EG_CB_COLOR6_CLEAR_WORD3 = 0x28E00, //
+ EG_CB_COLOR7_BASE = 0x28E04, // SAME 0x2805C
+ EG_CB_COLOR7_PITCH = 0x28E08, //
+ EG_CB_COLOR7_SLICE = 0x28E0C, //
+ EG_CB_COLOR7_VIEW = 0x28E10, // SAME 0x2809C
+ EG_CB_COLOR7_INFO = 0x28E14, // DIFF 0x280BC
+ EG_CB_COLOR7_ATTRIB = 0x28E18, //
+ EG_CB_COLOR7_DIM = 0x28E1C, //
+ EG_CB_COLOR7_CMASK = 0x28E20, //
+ EG_CB_COLOR7_CMASK_SLICE = 0x28E24, //
+ EG_CB_COLOR7_FMASK = 0x28E28, //
+ EG_CB_COLOR7_FMASK_SLICE = 0x28E2C, //
+ EG_CB_COLOR7_CLEAR_WORD0 = 0x28E30, //
+ EG_CB_COLOR7_CLEAR_WORD1 = 0x28E34, //
+ EG_CB_COLOR7_CLEAR_WORD2 = 0x28E38, //
+ EG_CB_COLOR7_CLEAR_WORD3 = 0x28E3C, //
+ EG_CB_COLOR8_BASE = 0x28E40, //
+ EG_CB_COLOR8_PITCH = 0x28E44, //
+ EG_CB_COLOR8_SLICE = 0x28E48, //
+ EG_CB_COLOR8_VIEW = 0x28E4C, //
+ EG_CB_COLOR8_INFO = 0x28E50, //
+ EG_CB_COLOR8_ATTRIB = 0x28E54, //
+ EG_CB_COLOR8_DIM = 0x28E58, //
+ EG_CB_COLOR9_BASE = 0x28E5C, //
+ EG_CB_COLOR9_PITCH = 0x28E60, //
+ EG_CB_COLOR9_SLICE = 0x28E64, //
+ EG_CB_COLOR9_VIEW = 0x28E68, //
+ EG_CB_COLOR9_INFO = 0x28E6C, //
+ EG_CB_COLOR9_ATTRIB = 0x28E70, //
+ EG_CB_COLOR9_DIM = 0x28E74, //
+ EG_CB_COLOR10_BASE = 0x28E78, //
+ EG_CB_COLOR10_PITCH = 0x28E7C, //
+ EG_CB_COLOR10_SLICE = 0x28E80, //
+ EG_CB_COLOR10_VIEW = 0x28E84, //
+ EG_CB_COLOR10_INFO = 0x28E88, //
+ EG_CB_COLOR10_ATTRIB = 0x28E8C, //
+ EG_CB_COLOR10_DIM = 0x28E90, //
+ EG_CB_COLOR11_BASE = 0x28E94, //
+ EG_CB_COLOR11_PITCH = 0x28E98, //
+ EG_CB_COLOR11_SLICE = 0x28E9C, //
+ EG_CB_COLOR11_VIEW = 0x28EA0, //
+ EG_CB_COLOR11_INFO = 0x28EA4, //
+ EG_CB_COLOR11_ATTRIB = 0x28EA8, //
+ EG_CB_COLOR11_DIM = 0x28EAC, //
+
+/* Registers from CP block: */
+ EG_COHER_DEST_BASE_0 = 0x28248, // SAME
+ EG_COHER_DEST_BASE_1 = 0x2824C, // SAME
+ EG_CP_PERFMON_CNTX_CNTL = 0x28358, //
+
+/* Config: */
+ EG_SPI_CONFIG_CNTL = 0x9100, // DIFF
+ EG_SPI_CONFIG_CNTL_1 = 0x913C, // DIFF
+ EG_CP_PERFMON_CNTL = 0x87FC, // SAME
+ EG_SQ_MS_FIFO_SIZES = 0x8CF0, // SAME
+ EG_SQ_CONFIG = 0x8C00, // DIFF
+ EG_SQ_GPR_RESOURCE_MGMT_1 = 0x8C04, // SAME
+ EG_SQ_GPR_RESOURCE_MGMT_2 = 0x8C08, // SAME
+ EG_SQ_THREAD_RESOURCE_MGMT = 0x8C18, // SAME 0x8C0C,
+ EG_SQ_STACK_RESOURCE_MGMT_1 = 0x8C20, // SAME 0x8C10,
+ EG_SQ_STACK_RESOURCE_MGMT_2 = 0x8C24, // SAME 0x8C14,
+ EG_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ = 0x8D8C, // DIFF
+ EG_SQ_LDS_RESOURCE_MGMT = 0x8E2C, //
+ EG_SQ_GPR_RESOURCE_MGMT_3 = 0x8C0C, //
+ EG_SQ_STACK_RESOURCE_MGMT_3 = 0x8C28, //
+ EG_SQ_THREAD_RESOURCE_MGMT_2 = 0x8C1C, //
+ EG_VGT_CACHE_INVALIDATION = 0x88C4, // DIFF
+ EG_VGT_GS_VERTEX_REUSE = 0x88D4, // SAME
+ EG_PA_SC_FORCE_EOV_MAX_CNTS = 0x8B24, // SAME
+ EG_PA_SC_LINE_STIPPLE_STATE = 0x8B10, // SAME
+ EG_PA_CL_ENHANCE = 0x8A14, // SAME
+
+/* Tex border color */
+ EG_TD_PS_BORDER_COLOR_RED = 0xA404,
+ EG_TD_PS_BORDER_COLOR_GREEN = 0xA408,
+ EG_TD_PS_BORDER_COLOR_BLUE = 0xA40C,
+ EG_TD_PS_BORDER_COLOR_ALPHA = 0xA410,
+
+/* const */
+ EG_SQ_VTX_CONSTANT_WORD0_0 = 0x30000, // 0x38000
+};
+
+#endif /* _EVERGREEN_OFF_H_ */ \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/evergreen_oglprog.c b/src/mesa/drivers/dri/r600/evergreen_oglprog.c
new file mode 100644
index 00000000000..9fe523234cc
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_oglprog.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#include <string.h>
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "program/program.h"
+
+#include "tnl/tnl.h"
+
+#include "r600_context.h"
+#include "r600_emit.h"
+
+#include "evergreen_oglprog.h"
+#include "evergreen_fragprog.h"
+#include "evergreen_vertprog.h"
+
+
+static void evergreen_freeVertProgCache(GLcontext *ctx, struct r700_vertex_program_cont *cache)
+{
+ struct evergreen_vertex_program *tmp, *vp = cache->progs;
+
+ while (vp) {
+ tmp = vp->next;
+ /* Release DMA region */
+ r600DeleteShader(ctx, vp->shaderbo);
+
+ if(NULL != vp->constbo0)
+ {
+ r600DeleteShader(ctx, vp->constbo0);
+ }
+
+ /* Clean up */
+ Clean_Up_Assembler(&(vp->r700AsmCode));
+ Clean_Up_Shader(&(vp->r700Shader));
+
+ _mesa_reference_vertprog(ctx, &vp->mesa_program, NULL);
+ free(vp);
+ vp = tmp;
+ }
+}
+
+static struct gl_program *evergreenNewProgram(GLcontext * ctx,
+ GLenum target,
+ GLuint id)
+{
+ struct gl_program *pProgram = NULL;
+
+ struct evergreen_vertex_program_cont *vpc;
+ struct evergreen_fragment_program *fp;
+
+ radeon_print(RADEON_SHADER, RADEON_VERBOSE,
+ "%s %u, %u\n", __func__, target, id);
+
+ switch (target)
+ {
+ case GL_VERTEX_STATE_PROGRAM_NV:
+ case GL_VERTEX_PROGRAM_ARB:
+ vpc = CALLOC_STRUCT(evergreen_vertex_program_cont);
+ pProgram = _mesa_init_vertex_program(ctx,
+ &vpc->mesa_program,
+ target,
+ id);
+
+ break;
+ case GL_FRAGMENT_PROGRAM_NV:
+ case GL_FRAGMENT_PROGRAM_ARB:
+ fp = CALLOC_STRUCT(evergreen_fragment_program);
+ pProgram = _mesa_init_fragment_program(ctx,
+ &fp->mesa_program,
+ target,
+ id);
+ fp->translated = GL_FALSE;
+ fp->loaded = GL_FALSE;
+
+ fp->shaderbo = NULL;
+
+ fp->constbo0 = NULL;
+
+ break;
+ default:
+ _mesa_problem(ctx, "Bad target in evergreenNewProgram");
+ }
+
+ return pProgram;
+}
+
+static void evergreenDeleteProgram(GLcontext * ctx, struct gl_program *prog)
+{
+ struct evergreen_vertex_program_cont *vpc = (struct evergreen_vertex_program_cont *)prog;
+ struct evergreen_fragment_program * fp;
+
+ radeon_print(RADEON_SHADER, RADEON_VERBOSE,
+ "%s %p\n", __func__, prog);
+
+ switch (prog->Target)
+ {
+ case GL_VERTEX_STATE_PROGRAM_NV:
+ case GL_VERTEX_PROGRAM_ARB:
+ evergreen_freeVertProgCache(ctx, vpc);
+ break;
+ case GL_FRAGMENT_PROGRAM_NV:
+ case GL_FRAGMENT_PROGRAM_ARB:
+ fp = (struct evergreen_fragment_program*)prog;
+ /* Release DMA region */
+
+ r600DeleteShader(ctx, fp->shaderbo);
+
+ if(NULL != fp->constbo0)
+ {
+ r600DeleteShader(ctx, fp->constbo0);
+ }
+
+ /* Clean up */
+ Clean_Up_Assembler(&(fp->r700AsmCode));
+ Clean_Up_Shader(&(fp->r700Shader));
+ break;
+ default:
+ _mesa_problem(ctx, "Bad target in evergreenNewProgram");
+ }
+
+ _mesa_delete_program(ctx, prog);
+}
+
+static GLboolean
+evergreenProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
+{
+ struct evergreen_vertex_program_cont *vpc = (struct evergreen_vertex_program_cont *)prog;
+ struct evergreen_fragment_program * fp = (struct evergreen_fragment_program*)prog;
+
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ evergreen_freeVertProgCache(ctx, vpc);
+ vpc->progs = NULL;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ r600DeleteShader(ctx, fp->shaderbo);
+
+ if(NULL != fp->constbo0)
+ {
+ r600DeleteShader(ctx, fp->constbo0);
+ fp->constbo0 = NULL;
+ }
+
+ Clean_Up_Assembler(&(fp->r700AsmCode));
+ Clean_Up_Shader(&(fp->r700Shader));
+ fp->translated = GL_FALSE;
+ fp->loaded = GL_FALSE;
+ fp->shaderbo = NULL;
+ break;
+ }
+
+ /* XXX check if program is legal, within limits */
+ return GL_TRUE;
+}
+
+static GLboolean evergreenIsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
+{
+
+ return GL_TRUE;
+}
+
+void evergreenInitShaderFuncs(struct dd_function_table *functions)
+{
+ functions->NewProgram = evergreenNewProgram;
+ functions->DeleteProgram = evergreenDeleteProgram;
+ functions->ProgramStringNotify = evergreenProgramStringNotify;
+ functions->IsProgramNative = evergreenIsProgramNative;
+}
diff --git a/src/mesa/slang/library/slang_builtin_120_fragment.gc b/src/mesa/drivers/dri/r600/evergreen_oglprog.h
index 7d516046a18..1cf3e79d05c 100644
--- a/src/mesa/slang/library/slang_builtin_120_fragment.gc
+++ b/src/mesa/drivers/dri/r600/evergreen_oglprog.h
@@ -1,8 +1,5 @@
/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -17,14 +14,20 @@
* 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
+ * THE COPYRIGHT HOLDER(S) 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.
*/
-//
-// From Shader Spec, ver. 1.20, rev. 6
-//
+/*
+ * Authors:
+ */
+
+#ifndef _EVERGREEN_OGLPROG_H_
+#define _EVERGREEN_OGLPROG_H_
+#include "r600_context.h"
-varying vec2 gl_PointCoord;
+extern void evergreenInitShaderFuncs(struct dd_function_table *functions);
+#endif /*_EVERGREEN_OGLPROG_H_*/
diff --git a/src/mesa/drivers/dri/r600/evergreen_render.c b/src/mesa/drivers/dri/r600/evergreen_render.c
new file mode 100644
index 00000000000..85b2f9d6ab7
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_render.c
@@ -0,0 +1,937 @@
+/*
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#include "main/glheader.h"
+#include "main/state.h"
+#include "main/imports.h"
+#include "main/enums.h"
+#include "main/macros.h"
+#include "main/context.h"
+#include "main/dd.h"
+#include "main/simple_list.h"
+#include "main/api_arrayelt.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "vbo/vbo.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_vp_build.h"
+#include "tnl/t_context.h"
+#include "tnl/t_vertex.h"
+#include "vbo/vbo_context.h"
+
+#include "r600_context.h"
+#include "r600_cmdbuf.h"
+
+#include "evergreen_fragprog.h"
+#include "evergreen_vertprog.h"
+
+#include "evergreen_state.h"
+#include "evergreen_tex.h"
+
+#include "radeon_buffer_objects.h"
+#include "radeon_common_context.h"
+
+static unsigned int evergreenPrimitiveType(int prim) //same
+{
+ switch (prim & PRIM_MODE_MASK)
+ {
+ case GL_POINTS:
+ return DI_PT_POINTLIST;
+ break;
+ case GL_LINES:
+ return DI_PT_LINELIST;
+ break;
+ case GL_LINE_STRIP:
+ return DI_PT_LINESTRIP;
+ break;
+ case GL_LINE_LOOP:
+ return DI_PT_LINELOOP;
+ break;
+ case GL_TRIANGLES:
+ return DI_PT_TRILIST;
+ break;
+ case GL_TRIANGLE_STRIP:
+ return DI_PT_TRISTRIP;
+ break;
+ case GL_TRIANGLE_FAN:
+ return DI_PT_TRIFAN;
+ break;
+ case GL_QUADS:
+ return DI_PT_QUADLIST;
+ break;
+ case GL_QUAD_STRIP:
+ return DI_PT_QUADSTRIP;
+ break;
+ case GL_POLYGON:
+ return DI_PT_POLYGON;
+ break;
+ default:
+ assert(0);
+ return -1;
+ break;
+ }
+}
+
+static int evergreenNumVerts(int num_verts, int prim) //same
+{
+ int verts_off = 0;
+
+ switch (prim & PRIM_MODE_MASK) {
+ case GL_POINTS:
+ verts_off = 0;
+ break;
+ case GL_LINES:
+ verts_off = num_verts % 2;
+ break;
+ case GL_LINE_STRIP:
+ if (num_verts < 2)
+ verts_off = num_verts;
+ break;
+ case GL_LINE_LOOP:
+ if (num_verts < 2)
+ verts_off = num_verts;
+ break;
+ case GL_TRIANGLES:
+ verts_off = num_verts % 3;
+ break;
+ case GL_TRIANGLE_STRIP:
+ if (num_verts < 3)
+ verts_off = num_verts;
+ break;
+ case GL_TRIANGLE_FAN:
+ if (num_verts < 3)
+ verts_off = num_verts;
+ break;
+ case GL_QUADS:
+ verts_off = num_verts % 4;
+ break;
+ case GL_QUAD_STRIP:
+ if (num_verts < 4)
+ verts_off = num_verts;
+ else
+ verts_off = num_verts % 2;
+ break;
+ case GL_POLYGON:
+ if (num_verts < 3)
+ verts_off = num_verts;
+ break;
+ default:
+ assert(0);
+ return -1;
+ break;
+ }
+
+ return num_verts - verts_off;
+}
+
+static void evergreenRunRenderPrimitive(GLcontext * ctx, int start, int end, int prim) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ BATCH_LOCALS(&context->radeon);
+ int type, total_emit;
+ int num_indices;
+ uint32_t vgt_draw_initiator = 0;
+ uint32_t vgt_index_type = 0;
+ uint32_t vgt_primitive_type = 0;
+ uint32_t vgt_num_indices = 0;
+
+ type = evergreenPrimitiveType(prim);
+ num_indices = evergreenNumVerts(end - start, prim);
+
+ radeon_print(RADEON_RENDER, RADEON_TRACE,
+ "%s type %x num_indices %d\n",
+ __func__, type, num_indices);
+
+ if (type < 0 || num_indices <= 0)
+ return;
+
+ SETfield(vgt_primitive_type, type,
+ VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
+
+ SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+
+ if(GL_TRUE != context->ind_buf.is_32bit)
+ {
+ SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+ }
+
+ vgt_num_indices = num_indices;
+ SETfield(vgt_draw_initiator, DI_SRC_SEL_DMA, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+ SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
+
+ total_emit = 3 /* VGT_PRIMITIVE_TYPE */
+ + 2 /* VGT_INDEX_TYPE */
+ + 2 /* NUM_INSTANCES */
+ + 5 + 2; /* DRAW_INDEX */
+
+ BEGIN_BATCH_NO_AUTOSTATE(total_emit);
+ // prim
+ R600_OUT_BATCH_REGSEQ(VGT_PRIMITIVE_TYPE, 1);
+ R600_OUT_BATCH(vgt_primitive_type);
+ // index type
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
+ R600_OUT_BATCH(vgt_index_type);
+ // num instances
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
+ R600_OUT_BATCH(1);
+ // draw packet
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX, 3));
+ R600_OUT_BATCH(context->ind_buf.bo_offset);
+ R600_OUT_BATCH(0);
+ R600_OUT_BATCH(vgt_num_indices);
+ R600_OUT_BATCH(vgt_draw_initiator);
+ R600_OUT_BATCH_RELOC(context->ind_buf.bo_offset,
+ context->ind_buf.bo,
+ context->ind_buf.bo_offset,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void evergreenRunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end, int prim) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ BATCH_LOCALS(&context->radeon);
+ int type, i;
+ uint32_t num_indices, total_emit = 0;
+ uint32_t vgt_draw_initiator = 0;
+ uint32_t vgt_index_type = 0;
+ uint32_t vgt_primitive_type = 0;
+ uint32_t vgt_num_indices = 0;
+
+ type = evergreenPrimitiveType(prim);
+ num_indices = evergreenNumVerts(end - start, prim);
+
+ radeon_print(RADEON_RENDER, RADEON_TRACE,
+ "%s type %x num_indices %d\n",
+ __func__, type, num_indices);
+
+ if (type < 0 || num_indices <= 0)
+ return;
+
+ SETfield(vgt_primitive_type, type,
+ VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
+
+ if (num_indices > 0xffff)
+ {
+ SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+ }
+ else
+ {
+ SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+ }
+
+ vgt_num_indices = num_indices;
+ SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
+
+ if (start == 0)
+ {
+ SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+ }
+ else
+ {
+ if (num_indices > 0xffff)
+ {
+ total_emit += num_indices;
+ }
+ else
+ {
+ total_emit += (num_indices + 1) / 2;
+ }
+ SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+ }
+
+ total_emit += 3 /* VGT_PRIMITIVE_TYPE */
+ + 2 /* VGT_INDEX_TYPE */
+ + 2 /* NUM_INSTANCES */
+ + 3; /* DRAW */
+
+ BEGIN_BATCH_NO_AUTOSTATE(total_emit);
+ // prim
+ R600_OUT_BATCH_REGSEQ(VGT_PRIMITIVE_TYPE, 1);
+ R600_OUT_BATCH(vgt_primitive_type);
+ // index type
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
+ R600_OUT_BATCH(vgt_index_type);
+ // num instances
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
+ R600_OUT_BATCH(1);
+ // draw packet
+ if(start == 0)
+ {
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
+ R600_OUT_BATCH(vgt_num_indices);
+ R600_OUT_BATCH(vgt_draw_initiator);
+ }
+ else
+ {
+ if (num_indices > 0xffff)
+ {
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1)));
+ R600_OUT_BATCH(vgt_num_indices);
+ R600_OUT_BATCH(vgt_draw_initiator);
+ for (i = start; i < (start + num_indices); i++)
+ {
+ R600_OUT_BATCH(i);
+ }
+ }
+ else
+ {
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (((num_indices + 1) / 2) + 1)));
+ R600_OUT_BATCH(vgt_num_indices);
+ R600_OUT_BATCH(vgt_draw_initiator);
+ for (i = start; i < (start + num_indices); i += 2)
+ {
+ if ((i + 1) == (start + num_indices))
+ {
+ R600_OUT_BATCH(i);
+ }
+ else
+ {
+ R600_OUT_BATCH(((i + 1) << 16) | (i));
+ }
+ }
+ }
+ }
+
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+#define CONVERT( TYPE, MACRO ) do { \
+ GLuint i, j, sz; \
+ sz = input->Size; \
+ if (input->Normalized) { \
+ for (i = 0; i < count; i++) { \
+ const TYPE *in = (TYPE *)src_ptr; \
+ for (j = 0; j < sz; j++) { \
+ *dst_ptr++ = MACRO(*in); \
+ in++; \
+ } \
+ src_ptr += stride; \
+ } \
+ } else { \
+ for (i = 0; i < count; i++) { \
+ const TYPE *in = (TYPE *)src_ptr; \
+ for (j = 0; j < sz; j++) { \
+ *dst_ptr++ = (GLfloat)(*in); \
+ in++; \
+ } \
+ src_ptr += stride; \
+ } \
+ } \
+} while (0)
+
+/**
+ * Convert attribute data type to float
+ * If the attribute uses named buffer object replace the bo with newly allocated bo
+ */
+static void evergreenConvertAttrib(GLcontext *ctx, int count,
+ const struct gl_client_array *input,
+ struct StreamDesc *attr)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ const GLvoid *src_ptr;
+ GLboolean mapped_named_bo = GL_FALSE;
+ GLfloat *dst_ptr;
+ GLuint stride;
+
+ stride = (input->StrideB == 0) ? evergreen_getTypeSize(input->Type) * input->Size : input->StrideB;
+
+ /* Convert value for first element only */
+ if (input->StrideB == 0)
+ {
+ count = 1;
+ }
+
+ if (input->BufferObj->Name)
+ {
+ if (!input->BufferObj->Pointer)
+ {
+ ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
+ mapped_named_bo = GL_TRUE;
+ }
+
+ src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
+ }
+ else
+ {
+ src_ptr = input->Ptr;
+ }
+
+ radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset,
+ sizeof(GLfloat) * input->Size * count, 32);
+
+ radeon_bo_map(attr->bo, 1);
+
+ dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
+
+ assert(src_ptr != NULL);
+
+ switch (input->Type)
+ {
+ case GL_DOUBLE:
+ CONVERT(GLdouble, (GLfloat));
+ break;
+ case GL_UNSIGNED_INT:
+ CONVERT(GLuint, UINT_TO_FLOAT);
+ break;
+ case GL_INT:
+ CONVERT(GLint, INT_TO_FLOAT);
+ break;
+ case GL_UNSIGNED_SHORT:
+ CONVERT(GLushort, USHORT_TO_FLOAT);
+ break;
+ case GL_SHORT:
+ CONVERT(GLshort, SHORT_TO_FLOAT);
+ break;
+ case GL_UNSIGNED_BYTE:
+ assert(input->Format != GL_BGRA);
+ CONVERT(GLubyte, UBYTE_TO_FLOAT);
+ break;
+ case GL_BYTE:
+ CONVERT(GLbyte, BYTE_TO_FLOAT);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ radeon_bo_unmap(attr->bo);
+
+ if (mapped_named_bo)
+ {
+ ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
+ }
+}
+
+static void evergreenFixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ GLvoid *src_ptr;
+ GLuint *out;
+ int i;
+ GLboolean mapped_named_bo = GL_FALSE;
+
+ if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer)
+ {
+ ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
+ mapped_named_bo = GL_TRUE;
+ assert(mesa_ind_buf->obj->Pointer != NULL);
+ }
+ src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
+
+ if (mesa_ind_buf->type == GL_UNSIGNED_BYTE)
+ {
+ GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
+ GLubyte *in = (GLubyte *)src_ptr;
+
+ radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
+ &context->ind_buf.bo_offset, size, 4);
+
+ radeon_bo_map(context->ind_buf.bo, 1);
+ assert(context->ind_buf.bo->ptr != NULL);
+ out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+
+ for (i = 0; i + 1 < mesa_ind_buf->count; i += 2)
+ {
+ *out++ = in[i] | in[i + 1] << 16;
+ }
+
+ if (i < mesa_ind_buf->count)
+ {
+ *out++ = in[i];
+ }
+
+ radeon_bo_unmap(context->ind_buf.bo);
+#if MESA_BIG_ENDIAN
+ }
+ else
+ { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
+ GLushort *in = (GLushort *)src_ptr;
+ GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
+
+ radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
+ &context->ind_buf.bo_offset, size, 4);
+
+ radeon_bo_map(context->ind_buf.bo, 1);
+ assert(context->ind_buf.bo->ptr != NULL);
+ out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+
+ for (i = 0; i + 1 < mesa_ind_buf->count; i += 2)
+ {
+ *out++ = in[i] | in[i + 1] << 16;
+ }
+
+ if (i < mesa_ind_buf->count)
+ {
+ *out++ = in[i];
+ }
+ radeon_bo_unmap(context->ind_buf.bo);
+#endif
+ }
+
+ context->ind_buf.is_32bit = GL_FALSE;
+ context->ind_buf.count = mesa_ind_buf->count;
+
+ if (mapped_named_bo)
+ {
+ ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
+ }
+}
+
+static GLboolean evergreen_check_fallbacks(GLcontext *ctx) //same
+{
+ if (ctx->RenderMode != GL_RENDER)
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+/* start 3d, idle, cb/db flush */
+#define PRE_EMIT_STATE_BUFSZ 5 + 5 + 14
+
+static GLuint evergreenPredictRenderSize(GLcontext* ctx,
+ const struct _mesa_prim *prim,
+ const struct _mesa_index_buffer *ib,
+ GLuint nr_prims)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ GLboolean flushed;
+ GLuint dwords, i;
+ GLuint state_size;
+
+ dwords = PRE_EMIT_STATE_BUFSZ;
+ if (ib)
+ dwords += nr_prims * 14;
+ else {
+ for (i = 0; i < nr_prims; ++i)
+ {
+ if (prim[i].start == 0)
+ dwords += 10;
+ else if (prim[i].count > 0xffff)
+ dwords += prim[i].count + 10;
+ else
+ dwords += ((prim[i].count + 1) / 2) + 10;
+ }
+ }
+
+ state_size = radeonCountStateEmitSize(&context->radeon);
+ flushed = rcommonEnsureCmdBufSpace(&context->radeon,
+ dwords + state_size,
+ __FUNCTION__);
+ if (flushed)
+ dwords += radeonCountStateEmitSize(&context->radeon);
+ else
+ dwords += state_size;
+
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s: total prediction size is %d.\n", __FUNCTION__, dwords);
+ return dwords;
+
+}
+
+static void evergreenSetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+
+ if (!mesa_ind_buf) {
+ context->ind_buf.bo = NULL;
+ return;
+ }
+
+#if MESA_BIG_ENDIAN
+ if (mesa_ind_buf->type == GL_UNSIGNED_INT)
+#else
+ if (mesa_ind_buf->type != GL_UNSIGNED_BYTE)
+#endif
+ {
+ const GLvoid *src_ptr;
+ GLvoid *dst_ptr;
+ GLboolean mapped_named_bo = GL_FALSE;
+
+ if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer)
+ {
+ ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
+ assert(mesa_ind_buf->obj->Pointer != NULL);
+ mapped_named_bo = GL_TRUE;
+ }
+
+ src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
+
+ const GLuint size = mesa_ind_buf->count * getTypeSize(mesa_ind_buf->type);
+
+ radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
+ &context->ind_buf.bo_offset, size, 4);
+ radeon_bo_map(context->ind_buf.bo, 1);
+ assert(context->ind_buf.bo->ptr != NULL);
+ dst_ptr = ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+
+ memcpy(dst_ptr, src_ptr, size);
+
+ radeon_bo_unmap(context->ind_buf.bo);
+ context->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
+ context->ind_buf.count = mesa_ind_buf->count;
+
+ if (mapped_named_bo)
+ {
+ ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
+ }
+ }
+ else
+ {
+ evergreenFixupIndexBuffer(ctx, mesa_ind_buf);
+ }
+}
+
+static void evergreenAlignDataToDword(GLcontext *ctx,
+ const struct gl_client_array *input,
+ int count,
+ struct StreamDesc *attr)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ const int dst_stride = (input->StrideB + 3) & ~3;
+ const int size = getTypeSize(input->Type) * input->Size * count;
+ GLboolean mapped_named_bo = GL_FALSE;
+
+ radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, size, 32);
+
+ radeon_bo_map(attr->bo, 1);
+
+ if (!input->BufferObj->Pointer)
+ {
+ ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
+ mapped_named_bo = GL_TRUE;
+ }
+
+ {
+ GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
+ GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
+ int i;
+
+ for (i = 0; i < count; ++i)
+ {
+ memcpy(dst_ptr, src_ptr, input->StrideB);
+ src_ptr += input->StrideB;
+ dst_ptr += dst_stride;
+ }
+ }
+
+ radeon_bo_unmap(attr->bo);
+ if (mapped_named_bo)
+ {
+ ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
+ }
+
+ attr->stride = dst_stride;
+}
+
+static void evergreenSetupStreams(GLcontext *ctx, const struct gl_client_array *input[], int count)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ GLuint stride;
+ int ret;
+ int i, index;
+
+ EVERGREEN_STATECHANGE(context, vtx);
+
+ for(index = 0; index < context->nNumActiveAos; index++)
+ {
+ struct radeon_aos *aos = &context->radeon.tcl.aos[index];
+ i = context->stream_desc[index].element;
+
+ stride = (input[i]->StrideB == 0) ? getTypeSize(input[i]->Type) * input[i]->Size : input[i]->StrideB;
+
+ if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT ||
+#if MESA_BIG_ENDIAN
+ getTypeSize(input[i]->Type) != 4 ||
+#endif
+ stride < 4)
+ {
+ evergreenConvertAttrib(ctx, count, input[i], &context->stream_desc[index]);
+ }
+ else
+ {
+ if (input[i]->BufferObj->Name)
+ {
+ if (stride % 4 != 0)
+ {
+ assert(((intptr_t) input[i]->Ptr) % input[i]->StrideB == 0);
+ evergreenAlignDataToDword(ctx, input[i], count, &context->stream_desc[index]);
+ context->stream_desc[index].is_named_bo = GL_FALSE;
+ }
+ else
+ {
+ context->stream_desc[index].stride = input[i]->StrideB;
+ context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr;
+ context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo;
+ context->stream_desc[index].is_named_bo = GL_TRUE;
+ }
+ }
+ else
+ {
+ int size;
+ int local_count = count;
+ uint32_t *dst;
+
+ if (input[i]->StrideB == 0)
+ {
+ size = getTypeSize(input[i]->Type) * input[i]->Size;
+ local_count = 1;
+ }
+ else
+ {
+ size = getTypeSize(input[i]->Type) * input[i]->Size * local_count;
+ }
+
+ radeonAllocDmaRegion(&context->radeon, &context->stream_desc[index].bo,
+ &context->stream_desc[index].bo_offset, size, 32);
+
+ radeon_bo_map(context->stream_desc[index].bo, 1);
+ assert(context->stream_desc[index].bo->ptr != NULL);
+
+
+ dst = (uint32_t *)ADD_POINTERS(context->stream_desc[index].bo->ptr,
+ context->stream_desc[index].bo_offset);
+
+ switch (context->stream_desc[index].dwords)
+ {
+ case 1:
+ radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count);
+ break;
+ case 2:
+ radeonEmitVec8(dst, input[i]->Ptr, input[i]->StrideB, local_count);
+ break;
+ case 3:
+ radeonEmitVec12(dst, input[i]->Ptr, input[i]->StrideB, local_count);
+ break;
+ case 4:
+ radeonEmitVec16(dst, input[i]->Ptr, input[i]->StrideB, local_count);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ radeon_bo_unmap(context->stream_desc[index].bo);
+ }
+ }
+
+ aos->count = context->stream_desc[index].stride == 0 ? 1 : count;
+ aos->stride = context->stream_desc[index].stride / sizeof(float);
+ aos->components = context->stream_desc[index].dwords;
+ aos->bo = context->stream_desc[index].bo;
+ aos->offset = context->stream_desc[index].bo_offset;
+
+ if(context->stream_desc[index].is_named_bo)
+ {
+ radeon_cs_space_add_persistent_bo(context->radeon.cmdbuf.cs,
+ context->stream_desc[index].bo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+ }
+
+ ret = radeon_cs_space_check_with_bo(context->radeon.cmdbuf.cs,
+ first_elem(&context->radeon.dma.reserved)->bo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+}
+
+static void evergreenFreeData(GLcontext *ctx)
+{
+ /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
+ * to prevent double unref in radeonReleaseArrays
+ * called during context destroy
+ */
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+
+ int i;
+
+ for (i = 0; i < context->nNumActiveAos; i++)
+ {
+ if (!context->stream_desc[i].is_named_bo)
+ {
+ radeon_bo_unref(context->stream_desc[i].bo);
+ }
+ context->radeon.tcl.aos[i].bo = NULL;
+ }
+
+ if(context->vp_Constbo != NULL)
+ {
+ radeon_bo_unref(context->vp_Constbo);
+ context->vp_Constbo = NULL;
+ }
+ if(context->fp_Constbo != NULL)
+ {
+ radeon_bo_unref(context->fp_Constbo);
+ context->fp_Constbo = NULL;
+ }
+
+ if (context->ind_buf.bo != NULL)
+ {
+ radeon_bo_unref(context->ind_buf.bo);
+ }
+}
+
+static GLboolean evergreenTryDrawPrims(GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index,
+ GLuint max_index )
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ radeonContextPtr radeon = &context->radeon;
+ GLuint i, id = 0;
+ struct radeon_renderbuffer *rrb;
+
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
+
+ if (evergreen_check_fallbacks(ctx))
+ return GL_FALSE;
+
+ _tnl_UpdateFixedFunctionProgram(ctx);
+ evergreenSetVertexFormat(ctx, arrays, max_index + 1);
+
+
+ /* shaders need to be updated before buffers are validated */
+ evergreenUpdateShaders(ctx);
+ if (!evergreenValidateBuffers(ctx))
+ return GL_FALSE;
+
+ /* always emit CB base to prevent
+ * lock ups on some chips.
+ */
+ EVERGREEN_STATECHANGE(context, cb);
+ /* mark vtx as dirty since it changes per-draw */
+ EVERGREEN_STATECHANGE(context, vtx);
+
+ evergreenSetScissor(context);
+
+ evergreenSetupVertexProgram(ctx);
+ evergreenSetupFragmentProgram(ctx);
+ evergreenUpdateShaderStates(ctx);
+
+ GLuint emit_end = evergreenPredictRenderSize(ctx, prim, ib, nr_prims)
+ + context->radeon.cmdbuf.cs->cdw;
+
+ /* evergreenPredictRenderSize will call radeonReleaseDmaRegions, so update VP/FP const buf after it. */
+ evergreenSetupVPconstants(ctx);
+ evergreenSetupFPconstants(ctx);
+
+ evergreenSetupIndexBuffer(ctx, ib);
+
+ evergreenSetupStreams(ctx, arrays, max_index + 1);
+
+ radeonEmitState(radeon);
+
+ radeon_debug_add_indent();
+
+ for (i = 0; i < nr_prims; ++i)
+ {
+ if (context->ind_buf.bo)
+ evergreenRunRenderPrimitive(ctx,
+ prim[i].start,
+ prim[i].start + prim[i].count,
+ prim[i].mode);
+ else
+ evergreenRunRenderPrimitiveImmediate(ctx,
+ prim[i].start,
+ prim[i].start + prim[i].count,
+ prim[i].mode);
+ }
+
+ radeon_debug_remove_indent();
+
+ /* Flush render op cached for last several quads. */
+ /* XXX drm should handle this in fence submit */
+
+ //evergreeWaitForIdleClean(context);
+
+ rrb = radeon_get_colorbuffer(&context->radeon);
+ if (rrb && rrb->bo)
+ r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
+ CB_ACTION_ENA_bit | (1 << (id + 6)));
+
+ rrb = radeon_get_depthbuffer(&context->radeon);
+ if (rrb && rrb->bo)
+ r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
+ DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit);
+
+ evergreenFreeData(ctx);
+
+ if (emit_end < context->radeon.cmdbuf.cs->cdw)
+ {
+ WARN_ONCE("Rendering was %d commands larger than predicted size."
+ " We might overflow command buffer.\n", context->radeon.cmdbuf.cs->cdw - emit_end);
+ }
+
+ return GL_TRUE;
+}
+
+static void evergreenDrawPrims(GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index)
+{
+ GLboolean retval = GL_FALSE;
+
+ /* This check should get folded into just the places that
+ * min/max index are really needed.
+ */
+ if (!index_bounds_valid) {
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+ }
+
+ if (min_index) {
+ vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, evergreenDrawPrims );
+ return;
+ }
+
+ /* Make an attempt at drawing */
+ retval = evergreenTryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+
+ /* If failed run tnl pipeline - it should take care of fallbacks */
+ if (!retval) {
+ _swsetup_Wakeup(ctx);
+ _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+ }
+}
+
+void evergreenInitDraw(GLcontext *ctx)
+{
+ struct vbo_context *vbo = vbo_context(ctx);
+
+ /* to be enabled */
+ vbo->draw_prims = evergreenDrawPrims;
+}
+
+
diff --git a/src/mesa/drivers/dri/r600/evergreen_sq.h b/src/mesa/drivers/dri/r600/evergreen_sq.h
new file mode 100644
index 00000000000..b1a536e76f6
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_sq.h
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#ifndef _EVERGREEN_SQ_H_
+#define _EVERGREEN_SQ_H_
+
+enum{
+//CF
+ EG_CF_WORD0__ADDR_shift = 0,
+ EG_CF_WORD0__ADDR_mask = 0xFFFFFF,
+ EG_CF_WORD0__JUMPTABLE_SEL_shift = 24,
+ EG_CF_WORD0__JUMPTABLE_SEL_mask = 0x7 << 24,
+
+ EG_CF_WORD1__POP_COUNT_shift = 0, //3 bits
+ EG_CF_WORD1__POP_COUNT_mask = 0x7,
+ EG_CF_WORD1__CF_CONST_shift = 3, //5 bits
+ EG_CF_WORD1__CF_CONST_mask = 0x1F << 3,
+ EG_CF_WORD1__COND_shift = 8, //2 bits
+ EG_CF_WORD1__COND_mask = 0x3 << 8,
+ EG_CF_WORD1__COUNT_shift = 10,//6 bits
+ EG_CF_WORD1__COUNT_mask = 0x3F << 10,
+ EG_CF_WORD1__reserved_shift = 16,//4 bits
+ EG_CF_WORD1__VPM_shift = 20,//1 bit
+ EG_CF_WORD1__VPM_bit = 1 << 20,
+ EG_CF_WORD1__EOP_shift = 21,//1 bit
+ EG_CF_WORD1__EOP_bit = 1 << 21,
+ EG_CF_WORD1__CF_INST_shift = 22,//8 bits
+ EG_CF_WORD1__CF_INST_mask = 0xFF << 22,
+ EG_CF_WORD1__WQM_shift = 30,//1 bit
+ EG_CF_WORD1__WQM_bit = 1 << 30,
+ EG_CF_WORD1__BARRIER_shift = 31,//1 bit
+ EG_CF_WORD1__BARRIER_bit = 1 << 31,
+
+ EG_CF_INST_NOP = 0,
+ EG_CF_INST_TC = 1,
+ EG_CF_INST_VC = 2,
+ EG_CF_INST_GDS = 3,
+ EG_CF_INST_LOOP_START = 4,
+ EG_CF_INST_LOOP_END = 5,
+ EG_CF_INST_LOOP_START_DX10 = 6,
+ EG_CF_INST_LOOP_START_NO_AL = 7,
+ EG_CF_INST_LOOP_CONTINUE = 8,
+ EG_CF_INST_LOOP_BREAK = 9,
+ EG_CF_INST_JUMP = 10,
+ EG_CF_INST_PUSH = 11,
+ EG_CF_INST_Reserved_12 = 12,
+ EG_CF_INST_ELSE = 13,
+ EG_CF_INST_POP = 14,
+ EG_CF_INST_Reserved_15 = 15,
+ EG_CF_INST_Reserved_16 = 16,
+ EG_CF_INST_Reserved_17 = 17,
+ EG_CF_INST_CALL = 18,
+ EG_CF_INST_CALL_FS = 19,
+ EG_CF_INST_RETURN = 20,
+ EG_CF_INST_EMIT_VERTEX = 21,
+ EG_CF_INST_EMIT_CUT_VERTEX = 22,
+ EG_CF_INST_CUT_VERTEX = 23,
+ EG_CF_INST_KILL = 24,
+ EG_CF_INST_Reserved_25 = 25,
+ EG_CF_INST_WAIT_ACK = 26,
+ EG_CF_INST_TC_ACK = 27,
+ EG_CF_INST_VC_ACK = 28,
+ EG_CF_INST_JUMPTABLE = 29,
+ EG_CF_INST_GLOBAL_WAVE_SYNC = 30,
+ EG_CF_INST_HALT = 31,
+
+//TEX
+ EG_TEX_WORD0__TEX_INST_shift = 0, //5 bits
+ EG_TEX_WORD0__TEX_INST_mask = 0x1F,
+ EG_TEX_WORD0__INST_MOD_shift = 5, //2 bits
+ EG_TEX_WORD0__INST_MOD_mask = 0x3 << 5,
+ EG_TEX_WORD0__FWQ_shift = 7, //1 bit
+ EG_TEX_WORD0__FWQ_bit = 1 << 7,
+ EG_TEX_WORD0__RESOURCE_ID_shift = 8, //8 bits
+ EG_TEX_WORD0__RESOURCE_ID_mask = 0xFF << 8,
+ EG_TEX_WORD0__SRC_GPR_shift = 16,//7 bits
+ EG_TEX_WORD0__SRC_GPR_mask = 0x7F << 16,
+ EG_TEX_WORD0__SRC_REL_shift = 23,//1 bit
+ EG_TEX_WORD0__SRC_REL_bit = 1 << 23,
+ EG_TEX_WORD0__ALT_CONST_shift = 24,//1 bit
+ EG_TEX_WORD0__ALT_CONST_bit = 1 << 24,
+ EG_TEX_WORD0__RIM_shift = 25,//2 bits
+ EG_TEX_WORD0__RIM_mask = 0x3 << 25,
+ EG_TEX_WORD0__SIM_shift = 27,//2 bits
+ EG_TEX_WORD0__SIM_mask = 0x3 << 27,
+ EG_TEX_WORD0__Reserved_shift = 29,//3 bits
+ EG_TEX_WORD0__Reserved_mask = 0x7 << 29,
+
+ EG_TEX_INST_Reserved_0 = 0,
+ EG_TEX_INST_Reserved_1 = 1,
+ EG_TEX_INST_Reserved_2 = 2,
+ EG_TEX_INST_LD = 3,
+ EG_TEX_INST_GET_TEXTURE_RESINFO = 4,
+ EG_TEX_INST_GET_NUMBER_OF_SAMPLES= 5,
+ EG_TEX_INST_GET_COMP_TEX_LOD = 6,
+ EG_TEX_INST_GET_GRADIENTS_H = 7,
+ EG_TEX_INST_GET_GRADIENTS_V = 8,
+ EG_TEX_INST_SET_TEXTURE_OFFSETS = 9,
+ EG_TEX_INST_KEEP_GRADIENTS = 10,
+ EG_TEX_INST_SET_GRADIENTS_H = 11,
+ EG_TEX_INST_SET_GRADIENTS_V = 12,
+ EG_TEX_INST_Reserved_13 = 13,
+ EG_TEX_INST_Reserved_14 = 14,
+ EG_TEX_INST_Reserved_15 = 15,
+ EG_TEX_INST_SAMPLE = 16,
+ EG_TEX_INST_SAMPLE_L = 17,
+ EG_TEX_INST_SAMPLE_LB = 18,
+ EG_TEX_INST_SAMPLE_LZ = 19,
+ EG_TEX_INST_SAMPLE_G = 20,
+ EG_TEX_INST_GATHER4 = 21,
+ EG_TEX_INST_SAMPLE_G_LB = 22,
+ EG_TEX_INST_GATHER4_O = 23,
+ EG_TEX_INST_SAMPLE_C = 24,
+ EG_TEX_INST_SAMPLE_C_L = 25,
+ EG_TEX_INST_SAMPLE_C_LB = 26,
+ EG_TEX_INST_SAMPLE_C_LZ = 27,
+ EG_TEX_INST_SAMPLE_C_G = 28,
+ EG_TEX_INST_GATHER4_C = 29,
+ EG_TEX_INST_SAMPLE_C_G_LB = 30,
+ EG_TEX_INST_GATHER4_C_O = 31,
+
+ EG_TEX_WORD1__DST_GPR_shift = 0, //7 bits
+ EG_TEX_WORD1__DST_GPR_mask = 0x7F,
+ EG_TEX_WORD1__DST_REL_shift = 7, //1 bit
+ EG_TEX_WORD1__DST_REL_bit = 1 << 7,
+ EG_TEX_WORD1__Reserved_shift = 8, //1 bit
+ EG_TEX_WORD1__Reserved_bit = 1 << 8,
+ EG_TEX_WORD1__DST_SEL_X_shift = 9, //3 bits
+ EG_TEX_WORD1__DST_SEL_X_mask = 0x7 << 9,
+ EG_TEX_WORD1__DST_SEL_Y_shift = 12,//3 bits
+ EG_TEX_WORD1__DST_SEL_Y_mask = 0x7 << 12,
+ EG_TEX_WORD1__DST_SEL_Z_shift = 15,//3 bits
+ EG_TEX_WORD1__DST_SEL_Z_mask = 0x7 << 15,
+ EG_TEX_WORD1__DST_SEL_W_shift = 18,//3 bits
+ EG_TEX_WORD1__DST_SEL_W_mask = 0x7 << 18,
+ EG_TEX_WORD1__LOD_BIAS_shift = 21,//7 bits
+ EG_TEX_WORD1__LOD_BIAS_mask = 0x7F << 21,
+ EG_TEX_WORD1__COORD_TYPE_X_shift = 28,//1 bit
+ EG_TEX_WORD1__COORD_TYPE_X_bit = 1 << 28,
+ EG_TEX_WORD1__COORD_TYPE_Y_shift = 29,//1 bit
+ EG_TEX_WORD1__COORD_TYPE_Y_bit = 1 << 29,
+ EG_TEX_WORD1__COORD_TYPE_Z_shift = 30,//1 bit
+ EG_TEX_WORD1__COORD_TYPE_Z_bit = 1 << 30,
+ EG_TEX_WORD1__COORD_TYPE_W_shift = 31,//1 bit
+ EG_TEX_WORD1__COORD_TYPE_W_bit = 1 << 31,
+
+ EG_TEX_WORD2__OFFSET_X_shift = 0, //5 bits
+ EG_TEX_WORD2__OFFSET_X_mask = 0x1F,
+ EG_TEX_WORD2__OFFSET_Y_shift = 5, //5 bits
+ EG_TEX_WORD2__OFFSET_Y_mask = 0x1F << 5,
+ EG_TEX_WORD2__OFFSET_Z_shift = 10,//5 bits
+ EG_TEX_WORD2__OFFSET_Z_mask = 0x1F << 10,
+ EG_TEX_WORD2__SAMPLER_ID_shift = 15,//5 bits
+ EG_TEX_WORD2__SAMPLER_ID_mask = 0x1F << 15,
+ EG_TEX_WORD2__SRC_SEL_X_shift = 20,//3 bits
+ EG_TEX_WORD2__SRC_SEL_X_mask = 0x7 << 20,
+ EG_TEX_WORD2__SRC_SEL_Y_shift = 23,//3 bits
+ EG_TEX_WORD2__SRC_SEL_Y_mask = 0x7 << 23,
+ EG_TEX_WORD2__SRC_SEL_Z_shift = 26,//3 bits
+ EG_TEX_WORD2__SRC_SEL_Z_mask = 0x7 << 26,
+ EG_TEX_WORD2__SRC_SEL_W_shift = 29,//3 bits
+ EG_TEX_WORD2__SRC_SEL_W_mask = 0x7 << 29,
+
+//VTX
+ EG_VTX_WORD0__VC_INST_shift = 0, //5 bits
+ EG_VTX_WORD0__VC_INST_mask = 0x1F,
+ EG_VTX_WORD0__FETCH_TYPE_shift = 5, //2 bits
+ EG_VTX_WORD0__FETCH_TYPE_mask = 0x3 << 5,
+ EG_VTX_WORD0__FWQ_shift = 7, //1 bit
+ EG_VTX_WORD0__FWQ_bit = 1 << 7,
+ EG_VTX_WORD0__BUFFER_ID_shift = 8, //8 bits
+ EG_VTX_WORD0__BUFFER_ID_mask = 0xFF << 8,
+ EG_VTX_WORD0__SRC_GPR_shift = 16,//7 bits
+ EG_VTX_WORD0__SRC_GPR_mask = 0x7F << 16,
+ EG_VTX_WORD0__SRC_REL_shift = 23,//1 bit
+ EG_VTX_WORD0__SRC_REL_bit = 1 << 23,
+ EG_VTX_WORD0__SRC_SEL_X_shift = 24,//2 bits
+ EG_VTX_WORD0__SRC_SEL_X_mask = 0x3 << 24,
+ EG_VTX_WORD0__MFC_shift = 26,//6 bits
+ EG_VTX_WORD0__MFC_mask = 0x3F << 26,
+
+ EG_VC_INST_FETCH = 0,
+ EG_VC_INST_SEMANTIC = 1,
+ EG_VC_INST_Reserved_2 = 2,
+ EG_VC_INST_Reserved_3 = 3,
+ EG_VC_INST_Reserved_4 = 4,
+ EG_VC_INST_Reserved_5 = 5,
+ EG_VC_INST_Reserved_6 = 6,
+ EG_VC_INST_Reserved_7 = 7,
+ EG_VC_INST_Reserved_8 = 8,
+ EG_VC_INST_Reserved_9 = 9,
+ EG_VC_INST_Reserved_10 = 10,
+ EG_VC_INST_Reserved_11 = 11,
+ EG_VC_INST_Reserved_12 = 12,
+ EG_VC_INST_Reserved_13 = 13,
+ EG_VC_INST_GET_BUFFER_RESINFO = 14,
+
+ EG_VTX_FETCH_VERTEX_DATA = 0,
+ EG_VTX_FETCH_INSTANCE_DATA = 1,
+ EG_VTX_FETCH_NO_INDEX_OFFSET = 2,
+
+ EG_VTX_WORD1_SEM__SEMANTIC_ID_shift = 0, //8 bits
+ EG_VTX_WORD1_SEM__SEMANTIC_ID_mask = 0xFF,
+ EG_VTX_WORD1_GPR__DST_GPR_shift = 0, //7 bits
+ EG_VTX_WORD1_GPR__DST_GPR_mask = 0x7F,
+ EG_VTX_WORD1_GPR__DST_REL_shift = 7, //1 bit
+ EG_VTX_WORD1_GPR__DST_REL_bit = 1 << 7,
+ EG_VTX_WORD1__Reserved_shift = 8, //1 bit
+ EG_VTX_WORD1__Reserved_bit = 1 << 8,
+ EG_VTX_WORD1__DST_SEL_X_shift = 9, //3 bits
+ EG_VTX_WORD1__DST_SEL_X_mask = 0x7 << 9,
+ EG_VTX_WORD1__DST_SEL_Y_shift = 12,//3 bits
+ EG_VTX_WORD1__DST_SEL_Y_mask = 0x7 << 12,
+ EG_VTX_WORD1__DST_SEL_Z_shift = 15,//3 bits
+ EG_VTX_WORD1__DST_SEL_Z_mask = 0x7 << 15,
+ EG_VTX_WORD1__DST_SEL_W_shift = 18,//3 bits
+ EG_VTX_WORD1__DST_SEL_W_mask = 0x7 << 18,
+ EG_VTX_WORD1__UCF_shift = 21,//1 bit
+ EG_VTX_WORD1__UCF_bit = 1 << 21,
+ EG_VTX_WORD1__DATA_FORMAT_shift = 22,//6 bits
+ EG_VTX_WORD1__DATA_FORMAT_mask = 0x3F << 22,
+ EG_VTX_WORD1__NFA_shift = 28,//2 bits
+ EG_VTX_WORD1__NFA_mask = 0x3 << 28,
+ EG_VTX_WORD1__FCA_shift = 30,//1 bit
+ EG_VTX_WORD1__FCA_bit = 1 << 30,
+ EG_VTX_WORD1__SMA_shift = 31,//1 bit
+ EG_VTX_WORD1__SMA_bit = 1 << 31,
+
+ EG_VTX_WORD2__OFFSET_shift = 0, //16 bits
+ EG_VTX_WORD2__OFFSET_mask = 0xFFFF,
+ EG_VTX_WORD2__ENDIAN_SWAP_shift = 16,//2 bits
+ EG_VTX_WORD2__ENDIAN_SWAP_mask = 0x3 << 16,
+ EG_VTX_WORD2__CBNS_shift = 18,//1 bit
+ EG_VTX_WORD2__CBNS_bit = 1 << 18,
+ EG_VTX_WORD2__MEGA_FETCH_shift = 19,//1 bit
+ EG_VTX_WORD2__MEGA_FETCH_mask = 1 << 19,
+ EG_VTX_WORD2__ALT_CONST_shift = 20,//1 bit
+ EG_VTX_WORD2__ALT_CONST_mask = 1 << 20,
+ EG_VTX_WORD2__BIM_shift = 21,//2 bits
+ EG_VTX_WORD2__BIM_mask = 0x3 << 21,
+ EG_VTX_WORD2__Reserved_shift = 23,//9 bits
+ EG_VTX_WORD2__Reserved_mask = 0x1FF << 23,
+
+//CF_ALU
+ EG_CF_ALU_WORD0__ADDR_shift = 0, //22 bits
+ EG_CF_ALU_WORD0__ADDR_mask = 0x3FFFFF,
+ EG_CF_ALU_WORD0__KCACHE_BANK0_shift = 22,//4 bits
+ EG_CF_ALU_WORD0__KCACHE_BANK0_mask = 0xF << 22,
+ EG_CF_ALU_WORD0__KCACHE_BANK1_shift = 26,//4 bits
+ EG_CF_ALU_WORD0__KCACHE_BANK1_mask = 0xF << 26,
+ EG_CF_ALU_WORD0__KCACHE_MODE0_shift = 30,//2 bits
+ EG_CF_ALU_WORD0__KCACHE_MODE0_mask = 0x3 << 30,
+
+ EG_CF_ALU_WORD1__KCACHE_MODE1_shift = 0, //2 bits
+ EG_CF_ALU_WORD1__KCACHE_MODE1_mask = 0x3,
+ EG_CF_ALU_WORD1__KCACHE_ADDR0_shift = 2, //8 bits
+ EG_CF_ALU_WORD1__KCACHE_ADDR0_mask = 0xFF << 2,
+ EG_CF_ALU_WORD1__KCACHE_ADDR1_shift = 10, //8 bits
+ EG_CF_ALU_WORD1__KCACHE_ADDR1_mask = 0xFF << 10,
+ EG_CF_ALU_WORD1__COUNT_shift = 18, //7 bits
+ EG_CF_ALU_WORD1__COUNT_mask = 0x7F << 18,
+ EG_CF_ALU_WORD1__ALT_CONST_shift = 25, //1 bit
+ EG_CF_ALU_WORD1__ALT_CONST_bit = 1 << 25,
+ EG_CF_ALU_WORD1__CF_INST_shift = 26, //4 bits
+ EG_CF_ALU_WORD1__CF_INST_mask = 0xF << 26,
+ EG_CF_ALU_WORD1__WQM_shift = 30, //1 bit
+ EG_CF_ALU_WORD1__WQM_bit = 1 << 30,
+ EG_CF_ALU_WORD1__BARRIER_shift = 31, //1 bit
+ EG_CF_ALU_WORD1__BARRIER_bit = 1 << 31,
+
+ EG_CF_INST_ALU = 8,
+ EG_CF_INST_ALU_PUSH_BEFORE = 9,
+ EG_CF_INST_ALU_POP_AFTER = 10,
+ EG_CF_INST_ALU_POP2_AFTER = 11,
+ EG_CF_INST_ALU_EXTENDED = 12,
+ EG_CF_INST_ALU_CONTINUE = 13,
+ EG_CF_INST_ALU_BREAK = 14,
+ EG_CF_INST_ALU_ELSE_AFTER = 15,
+
+ EG_CF_ALU_WORD0_EXT__Reserved0_shift = 0, //4 bits
+ EG_CF_ALU_WORD0_EXT__Reserved0_mask = 0xF,
+ EG_CF_ALU_WORD0_EXT__KBIM0_shift = 4, //2 bits
+ EG_CF_ALU_WORD0_EXT__KBIM0_mask = 0x3 << 4,
+ EG_CF_ALU_WORD0_EXT__KBIM1_shift = 6, //2 bits
+ EG_CF_ALU_WORD0_EXT__KBIM1_mask = 0x3 << 6,
+ EG_CF_ALU_WORD0_EXT__KBIM2_shift = 8, //2 bits
+ EG_CF_ALU_WORD0_EXT__KBIM2_mask = 0x3 << 8,
+ EG_CF_ALU_WORD0_EXT__KBIM3_shift = 10,//2 bits
+ EG_CF_ALU_WORD0_EXT__KBIM3_mask = 0x3 << 10,
+ EG_CF_ALU_WORD0_EXT__Reserved12_shift = 12,//10 bits
+ EG_CF_ALU_WORD0_EXT__Reserved12_mask = 0x3FF << 12,
+ EG_CF_ALU_WORD0_EXT__KCACHE_BANK2_shift = 22,//4 bits
+ EG_CF_ALU_WORD0_EXT__KCACHE_BANK2_mask = 0xF << 22,
+ EG_CF_ALU_WORD0_EXT__KCACHE_BANK3_shift = 26,//4 bits
+ EG_CF_ALU_WORD0_EXT__KCACHE_BANK3_mask = 0xF << 26,
+ EG_CF_ALU_WORD0_EXT__KCACHE_MODE2_shift = 30,//2 btis
+ EG_CF_ALU_WORD0_EXT__KCACHE_MODE2_mask = 0x3 << 30,
+
+ EG_CF_ALU_WORD1_EXT__KCACHE_MODE3_shift = 0, //2 bits
+ EG_CF_ALU_WORD1_EXT__KCACHE_MODE3_mask = 0x3,
+ EG_CF_ALU_WORD1_EXT__KCACHE_ADDR2_shift = 2, //8 bits
+ EG_CF_ALU_WORD1_EXT__KCACHE_ADDR2_mask = 0xFF << 2,
+ EG_CF_ALU_WORD1_EXT__KCACHE_ADDR3_shift = 10, //8 bits
+ EG_CF_ALU_WORD1_EXT__KCACHE_ADDR3_mask = 0xFF << 10,
+ EG_CF_ALU_WORD1_EXT__Reserved18_shift = 18, //8 bits
+ EG_CF_ALU_WORD1_EXT__Reserved18_mask = 0xFF << 18,
+ EG_CF_ALU_WORD1_EXT__CF_INST_shift = 26, //4 bits
+ EG_CF_ALU_WORD1_EXT__CF_INST_mask = 0xF << 26,
+ EG_CF_ALU_WORD1_EXT__Reserved30_shift = 30, //1 bit
+ EG_CF_ALU_WORD1_EXT__Reserved30_bit = 1 << 30,
+ EG_CF_ALU_WORD1_EXT__BARRIER_shift = 31, //1 bit
+ EG_CF_ALU_WORD1_EXT__BARRIER_bit = 1 << 31,
+
+//ALU
+ EG_ALU_WORD0__SRC0_SEL_shift = 0, //9 bits
+ EG_ALU_WORD0__SRC0_SEL_mask = 0x1FF,
+ EG_ALU_WORD0__SRC1_SEL_shift = 13,//9 bits
+ EG_ALU_WORD0__SRC1_SEL_mask = 0x1FF << 13,
+ EG_ALU_WORD0__SRC0_REL_shift = 9, //1 bit
+ EG_ALU_WORD0__SRC0_REL_bit = 1 << 9,
+ EG_ALU_WORD0__SRC1_REL_shift = 22,//1 bit
+ EG_ALU_WORD0__SRC1_REL_bit = 1 << 22,
+ EG_ALU_WORD0__SRC0_CHAN_shift = 10,//2 bits
+ EG_ALU_WORD0__SRC0_CHAN_mask = 0x3 << 10,
+ EG_ALU_WORD0__SRC1_CHAN_shift = 23,//2 bits
+ EG_ALU_WORD0__SRC1_CHAN_mask = 0x3 << 23,
+ EG_ALU_WORD0__SRC0_NEG_shift = 12,//1 bit
+ EG_ALU_WORD0__SRC0_NEG_bit = 1 << 12,
+ EG_ALU_WORD0__SRC1_NEG_shift = 25,//1 bit
+ EG_ALU_WORD0__SRC1_NEG_bit = 1 << 25,
+ EG_ALU_WORD0__INDEX_MODE_shift = 26,//3 bits
+ EG_ALU_WORD0__INDEX_MODE_mask = 0x7 << 26,
+ EG_ALU_WORD0__PRED_SEL_shift = 29,//2 bits
+ EG_ALU_WORD0__PRED_SEL_mask = 0x3 << 29,
+ EG_ALU_WORD0__LAST_shift = 31,//1 bit
+ EG_ALU_WORD0__LAST_bit = 1 << 31,
+
+ EG_ALU_WORD1_OP2__SRC0_ABS_shift = 0, //1 bit
+ EG_ALU_WORD1_OP2__SRC0_ABS_bit = 1,
+ EG_ALU_WORD1_OP2__SRC1_ABS_shift = 1, //1 bit
+ EG_ALU_WORD1_OP2__SRC1_ABS_bit = 1 << 1,
+ EG_ALU_WORD1_OP2__UEM_shift = 2, //1 bit
+ EG_ALU_WORD1_OP2__UEM_bit = 1 << 2,
+ EG_ALU_WORD1_OP2__UPDATE_PRED_shift = 3, //1 bit
+ EG_ALU_WORD1_OP2__UPDATE_PRED_bit = 1 << 3,
+ EG_ALU_WORD1_OP2__WRITE_MASK_shift = 4, //1 bit
+ EG_ALU_WORD1_OP2__WRITE_MASK_bit = 1 << 4,
+ EG_ALU_WORD1_OP2__OMOD_shift = 5, //2 bits
+ EG_ALU_WORD1_OP2__OMOD_mask = 0x3 << 5,
+ EG_ALU_WORD1_OP2__ALU_INST_shift = 7, //11 bits
+ EG_ALU_WORD1_OP2__ALU_INST_mask = 0x7FF << 7,
+
+ EG_ALU_WORD1__BANK_SWIZZLE_shift = 18,//3 bits
+ EG_ALU_WORD1__BANK_SWIZZLE_mask = 0x7 << 18,
+ EG_ALU_WORD1__DST_GPR_shift = 21,//7 bits
+ EG_ALU_WORD1__DST_GPR_mask = 0x7F << 21,
+ EG_ALU_WORD1__DST_REL_shift = 28,//1 bit
+ EG_ALU_WORD1__DST_REL_mask = 1 << 28,
+ EG_ALU_WORD1__DST_CHAN_shift = 29,//2 bits
+ EG_ALU_WORD1__DST_CHAN_mask = 0x3 << 29,
+ EG_ALU_WORD1__CLAMP_shift = 31,//1 bits
+ EG_ALU_WORD1__CLAMP_mask = 1 << 31,
+
+ EG_ALU_WORD1_OP3__SRC2_SEL_shift = 0, //9 bits
+ EG_ALU_WORD1_OP3__SRC2_SEL_mask = 0x1FF,
+ EG_ALU_WORD1_OP3__SRC2_REL_shift = 9, //1 bit
+ EG_ALU_WORD1_OP3__SRC2_REL_bit = 1 << 9,
+ EG_ALU_WORD1_OP3__SRC2_CHAN_shift = 10,//2 bits
+ EG_ALU_WORD1_OP3__SRC2_CHAN_mask = 0x3 << 10,
+ EG_ALU_WORD1_OP3__SRC2_NEG_shift = 12,//1 bit
+ EG_ALU_WORD1_OP3__SRC2_NEG_bit = 1 << 12,
+ EG_ALU_WORD1_OP3__ALU_INST_shift = 13,//5 bits
+ EG_ALU_WORD1_OP3__ALU_INST_mask = 0x1F << 13,
+
+ EG_OP3_INST_BFE_UINT = 4,
+ EG_OP3_INST_BFE_INT = 5,
+ EG_OP3_INST_BFI_INT = 6,
+ EG_OP3_INST_FMA = 7,
+ EG_OP3_INST_CNDNE_64 = 9,
+ EG_OP3_INST_FMA_64 = 10,
+ EG_OP3_INST_LERP_UINT = 11,
+ EG_OP3_INST_BIT_ALIGN_INT = 12,
+ EG_OP3_INST_BYTE_ALIGN_INT = 13,
+ EG_OP3_INST_SAD_ACCUM_UINT = 14,
+ EG_OP3_INST_SAD_ACCUM_HI_UINT = 15,
+ EG_OP3_INST_MULADD_UINT24 = 16,
+ EG_OP3_INST_LDS_IDX_OP = 17,
+ EG_OP3_INST_MULADD = 20,
+ EG_OP3_INST_MULADD_M2 = 21,
+ EG_OP3_INST_MULADD_M4 = 22,
+ EG_OP3_INST_MULADD_D2 = 23,
+ EG_OP3_INST_MULADD_IEEE = 24,
+ EG_OP3_INST_CNDE = 25,
+ EG_OP3_INST_CNDGT = 26,
+ EG_OP3_INST_CNDGE = 27,
+ EG_OP3_INST_CNDE_INT = 28,
+ EG_OP3_INST_CMNDGT_INT = 29,
+ EG_OP3_INST_CMNDGE_INT = 30,
+ EG_OP3_INST_MUL_LIT = 31,
+
+ EG_OP2_INST_ADD = 0,
+ EG_OP2_INST_MUL = 1,
+ EG_OP2_INST_MUL_IEEE = 2,
+ EG_OP2_INST_MAX = 3,
+ EG_OP2_INST_MIN = 4,
+ EG_OP2_INST_MAX_DX10 = 5,
+ EG_OP2_INST_MIN_DX10 = 6,
+ EG_OP2_INST_SETE = 8,
+ EG_OP2_INST_SETGT = 9,
+ EG_OP2_INST_SETGE = 10,
+ EG_OP2_INST_SETNE = 11,
+ EG_OP2_INST_SETE_DX10 = 12,
+ EG_OP2_INST_SETGT_DX10 = 13,
+ EG_OP2_INST_SETGE_DX10 = 14,
+ EG_OP2_INST_SETNE_DX10 = 15,
+ EG_OP2_INST_FRACT = 16,
+ EG_OP2_INST_TRUNC = 17,
+ EG_OP2_INST_CEIL = 18,
+ EG_OP2_INST_RNDNE = 19,
+ EG_OP2_INST_FLOOR = 20,
+ EG_OP2_INST_ASHR_INT = 21,
+ EG_OP2_INST_LSHR_INT = 22,
+ EG_OP2_INST_LSHL_INT = 23,
+ EG_OP2_INST_MOV = 25,
+ EG_OP2_INST_NOP = 26,
+ EG_OP2_INST_MUL_64 = 27,
+ EG_OP2_INST_FLT64_TO_FLT32 = 28,
+ EG_OP2_INST_FLT32_TO_FLT64 = 29,
+ EG_OP2_INST_PRED_SETGT_UINT = 30,
+ EG_OP2_INST_PRED_SETGE_UINT = 31,
+ EG_OP2_INST_PRED_SETE = 32,
+ EG_OP2_INST_PRED_SETGT = 33,
+ EG_OP2_INST_PRED_SETGE = 34,
+ EG_OP2_INST_PRED_SETNE = 35,
+ EG_OP2_INST_PRED_SET_INV = 36,
+ EG_OP2_INST_PRED_SET_POP = 37,
+ EG_OP2_INST_PRED_SET_CLR = 38,
+ EG_OP2_INST_PRED_SET_RESTORE = 39,
+ EG_OP2_INST_PRED_SETE_PUSH = 40,
+ EG_OP2_INST_PRED_SETGT_PUSH = 41,
+ EG_OP2_INST_PRED_SETGE_PUSH = 42,
+ EG_OP2_INST_PRED_SETNE_PUSH = 43,
+ EG_OP2_INST_KILLE = 44,
+ EG_OP2_INST_KILLGT = 45,
+ EG_OP2_INST_KILLGE = 46,
+ EG_OP2_INST_KILLNE = 47,
+ EG_OP2_INST_AND_INT = 48,
+ EG_OP2_INST_OR_INT = 49,
+ EG_OP2_INST_XOR_INT = 50,
+ EG_OP2_INST_NOT_INT = 51,
+ EG_OP2_INST_ADD_INT = 52,
+ EG_OP2_INST_SUB_INT = 53,
+ EG_OP2_INST_MAX_INT = 54,
+ EG_OP2_INST_MIN_INT = 55,
+ EG_OP2_INST_MAX_UINT = 56,
+ EG_OP2_INST_MIN_UINT = 57,
+ EG_OP2_INST_SETE_INT = 58,
+ EG_OP2_INST_SETGT_INT = 59,
+ EG_OP2_INST_SETGE_INT = 60,
+ EG_OP2_INST_SETNE_INT = 61,
+ EG_OP2_INST_SETGT_UINT = 62,
+ EG_OP2_INST_SETGE_UINT = 63,
+ EG_OP2_INST_KILLGT_UINT = 64,
+ EG_OP2_INST_KILLGE_UINT = 65,
+ EG_OP2_INST_PREDE_INT = 66,
+ EG_OP2_INST_PRED_SETGT_INT = 67,
+ EG_OP2_INST_PRED_SETGE_INT = 68,
+ EG_OP2_INST_PRED_SETNE_INT = 69,
+ EG_OP2_INST_KILLE_INT = 70,
+ EG_OP2_INST_KILLGT_INT = 71,
+ EG_OP2_INST_KILLGE_INT = 72,
+ EG_OP2_INST_KILLNE_INT = 73,
+ EG_OP2_INST_PRED_SETE_PUSH_INT = 74,
+ EG_OP2_INST_PRED_SETGT_PUSH_INT = 75,
+ EG_OP2_INST_PRED_SETGE_PUSH_INT = 76,
+ EG_OP2_INST_PRED_SETNE_PUSH_INT = 77,
+ EG_OP2_INST_PRED_SETLT_PUSH_INT = 78,
+ EG_OP2_INST_PRED_SETLE_PUSH_INT = 79,
+ EG_OP2_INST_FLT_TO_INT = 80,
+ EG_OP2_INST_BFREV_INT = 81,
+ EG_OP2_INST_ADDC_UINT = 82,
+ EG_OP2_INST_SUBB_UINT = 83,
+ EG_OP2_INST_GROUP_BARRIER = 84,
+ EG_OP2_INST_GROUP_SEQ_BEGIN = 85,
+ EG_OP2_INST_GROUP_SEQ_END = 86,
+ EG_OP2_INST_SET_MODE = 87,
+ EG_OP2_INST_SET_CF_IDX0 = 88,
+ EG_OP2_INST_SET_CF_IDX1 = 89,
+ EG_OP2_INST_SET_LDS_SIZE = 90,
+ EG_OP2_INST_EXP_IEEE = 129,
+ EG_OP2_INST_LOG_CLAMPED = 130,
+ EG_OP2_INST_LOG_IEEE = 131,
+ EG_OP2_INST_RECIP_CLAMPED = 132,
+ EG_OP2_INST_RECIP_FF = 133,
+ EG_OP2_INST_RECIP_IEEE = 134,
+ EG_OP2_INST_RECIPSQRT_CLAMPED = 135,
+ EG_OP2_INST_RECIPSQRT_FF = 136,
+ EG_OP2_INST_RECIPSQRT_IEEE = 137,
+ EG_OP2_INST_SQRT_IEEE = 138,
+ EG_OP2_INST_SIN = 141,
+ EG_OP2_INST_COS = 142,
+ EG_OP2_INST_MULLO_INT = 143,
+ EG_OP2_INST_MULHI_INT = 144,
+ EG_OP2_INST_MULLO_UINT = 145,
+ EG_OP2_INST_MULHI_UINT = 146,
+ EG_OP2_INST_RECIP_INT = 147,
+ EG_OP2_INST_RECIP_UINT = 148,
+ EG_OP2_INST_RECIP_64 = 149,
+ EG_OP2_INST_RECIP_CLAMPED_64 = 150,
+ EG_OP2_INST_RECIPSQRT_64 = 151,
+ EG_OP2_INST_RECIPSQRT_CLAMPED_64 = 152,
+ EG_OP2_INST_SQRT_64 = 153,
+ EG_OP2_INST_FLT_TO_UINT = 154,
+ EG_OP2_INST_INT_TO_FLT = 155,
+ EG_OP2_INST_UINT_TO_FLT = 156,
+ EG_OP2_INST_BFM_INT = 160,
+ EG_OP2_INST_FLT32_TO_FLT16 = 162,
+ EG_OP2_INST_FLT16_TO_FLT32 = 163,
+ EG_OP2_INST_UBYTE0_FLT = 164,
+ EG_OP2_INST_UBYTE1_FLT = 165,
+ EG_OP2_INST_UBYTE2_FLT = 166,
+ EG_OP2_INST_UBYTE3_FLT = 167,
+ EG_OP2_INST_BCNT_INT = 170,
+ EG_OP2_INST_FFBH_UINT = 171,
+ EG_OP2_INST_FFBL_INT = 172,
+ EG_OP2_INST_FFBH_INT = 173,
+ EG_OP2_INST_FLT_TO_UINT4 = 174,
+ EG_OP2_INST_DOT_IEEE = 175,
+ EG_OP2_INST_FLT_TO_INT_RPI = 176,
+ EG_OP2_INST_FLT_TO_INT_FLOOR = 177,
+ EG_OP2_INST_MULHI_UINT24 = 178,
+ EG_OP2_INST_MBCNT_32HI_INT = 179,
+ EG_OP2_INST_OFFSET_TO_FLT = 180,
+ EG_OP2_INST_MUL_UINT24 = 181,
+ EG_OP2_INST_BCNT_ACCUM_PREV_INT = 182,
+ EG_OP2_INST_MBCNT_32LO_ACCUM_PREV_INT = 183,
+ EG_OP2_INST_SETE_64 = 184,
+ EG_OP2_INST_SETNE_64 = 185,
+ EG_OP2_INST_SETGT_64 = 186,
+ EG_OP2_INST_SETGE_64 = 187,
+ EG_OP2_INST_MIN_64 = 188,
+ EG_OP2_INST_MAX_64 = 189,
+ EG_OP2_INST_DOT4 = 190,
+ EG_OP2_INST_DOT4_IEEE = 191,
+ EG_OP2_INST_CUBE = 192,
+ EG_OP2_INST_MAX4 = 193,
+ EG_OP2_INST_FREXP_64 = 196,
+ EG_OP2_INST_LDEXP_64 = 197,
+ EG_OP2_INST_FRACT_64 = 198,
+ EG_OP2_INST_PRED_SETGT_64 = 199,
+ EG_OP2_INST_PRED_SETE_64 = 200,
+ EG_OP2_INST_PRED_SETGE_64 = 201,
+ EG_OP2_INST_MUL_64_2 = 202, //same as prev?
+ EG_OP2_INST_ADD_64 = 203,
+ EG_OP2_INST_MOVA_INT = 204,
+ EG_OP2_INST_FLT64_TO_FLT32_2 = 205, //same as prev?
+ EG_OP2_INST_FLT32_TO_FLT64_2 = 206, //same as prev?
+ EG_OP2_INST_SAD_ACCUM_PREV_UINT = 207,
+ EG_OP2_INST_DOT = 208,
+ EG_OP2_INST_MUL_PREV = 209,
+ EG_OP2_INST_MUL_IEEE_PREV = 210,
+ EG_OP2_INST_ADD_PREV = 211,
+ EG_OP2_INST_MULADD_PREV = 212,
+ EG_OP2_INST_MULADD_IEEE_PREV = 213,
+ EG_OP2_INST_INTERP_XY = 214,
+ EG_OP2_INST_INTERP_ZW = 215,
+ EG_OP2_INST_INTERP_X = 216,
+ EG_OP2_INST_INTERP_Z = 217,
+ EG_OP2_INST_STORE_FLAGS = 218,
+ EG_OP2_INST_LOAD_STORE_FLAGS = 219,
+ EG_OP2_INST_LDS_1A = 220,
+ EG_OP2_INST_LDS_1A1D = 221,
+ EG_OP2_INST_LDS_2A = 223,
+ EG_OP2_INST_INTERP_LOAD_P0 = 224,
+ EG_OP2_INST_INTERP_LOAD_P10 = 225,
+ EG_OP2_INST_INTERP_LOAD_P20 = 226,
+
+ EG_SRC_SEL__GPR_start = 0,
+ EG_SRC_SEL__GPR_end = 127,
+ EG_SRC_SEL__KCONST_BANK0_start = 128,
+ EG_SRC_SEL__KCONST_BANK0_end = 159,
+ EG_SRC_SEL__KCONST_BANK1_start = 160,
+ EG_SRC_SEL__KCONST_BANK1_end = 191,
+ EG_SRC_SEL__INLINE_satrt = 192,
+ EG_SRC_SEL__INLINE_end = 255,
+ EG_SRC_SEL__KCONST_BANK2_start = 256,
+ EG_SRC_SEL__KCONST_BANK2_end = 287,
+ EG_SRC_SEL__KCONST_BANK3_start = 288,
+ EG_SRC_SEL__KCONST_BANK3_end = 319,
+ EG_SRC_SEL__ALU_SRC_LDS_OQ_A = 219,
+ EG_SRC_SEL__ALU_SRC_LDS_OQ_B = 220,
+ EG_SRC_SEL__ALU_SRC_LDS_OQ_A_POP = 221,
+ EG_SRC_SEL__ALU_SRC_LDS_OQ_B_POP = 222,
+ EG_SRC_SEL__ALU_SRC_LDS_DIRECT_A = 223,
+ EG_SRC_SEL__ALU_SRC_LDS_DIRECT_B = 224,
+ EG_SRC_SEL__ALU_SRC_TIME_HI = 227,
+ EG_SRC_SEL__ALU_SRC_TIME_LO = 228,
+ EG_SRC_SEL__ALU_SRC_MASK_HI = 229,
+ EG_SRC_SEL__ALU_SRC_MASK_LO = 230,
+ EG_SRC_SEL__ALU_SRC_HW_WAVE_ID = 231,
+ EG_SRC_SEL__ALU_SRC_SIMD_ID = 232,
+ EG_SRC_SEL__ALU_SRC_SE_ID = 233,
+ EG_SRC_SEL__ALU_SRC_HW_THREADGRP_ID = 234,
+ EG_SRC_SEL__ALU_SRC_WAVE_ID_IN_GRP = 235,
+ EG_SRC_SEL__ALU_SRC_NUM_THREADGRP_WAVES = 236,
+ EG_SRC_SEL__ALU_SRC_HW_ALU_ODD = 237,
+ EG_SRC_SEL__ALU_SRC_LOOP_IDX = 238,
+ EG_SRC_SEL__ALU_SRC_PARAM_BASE_ADDR = 240,
+ EG_SRC_SEL__ALU_SRC_NEW_PRIM_MASK = 241,
+ EG_SRC_SEL__ALU_SRC_PRIM_MASK_HI = 242,
+ EG_SRC_SEL__ALU_SRC_PRIM_MASK_LO = 243,
+ EG_SRC_SEL__ALU_SRC_1_DBL_L = 244,
+ EG_SRC_SEL__ALU_SRC_1_DBL_M = 245,
+ EG_SRC_SEL__ALU_SRC_0_5_DBL_L = 246,
+ EG_SRC_SEL__ALU_SRC_0_5_DBL_M = 247,
+ EG_SRC_SEL__ALU_SRC_0 = 248,
+ EG_SRC_SEL__ALU_SRC_1 = 249,
+ EG_SRC_SEL__ALU_SRC_1_INT = 250,
+ EG_SRC_SEL__ALU_SRC_M_1_INT = 251,
+ EG_SRC_SEL__ALU_SRC_0_5 = 252,
+ EG_SRC_SEL__ALU_SRC_LITERAL = 253,
+ EG_SRC_SEL__ALU_SRC_PV = 254,
+ EG_SRC_SEL__ALU_SRC_PS = 255,
+
+//ALLOC_EXPORT
+ EG_CF_ALLOC_EXPORT_WORD0__ARRAY_BASE_shift = 0, //13 bits
+ EG_CF_ALLOC_EXPORT_WORD0__ARRAY_BASE_mask = 0x1FFF,
+ EG_CF_ALLOC_EXPORT_WORD0__TYPE_shift = 13,//2 bits
+ EG_CF_ALLOC_EXPORT_WORD0__TYPE_mask = 0x3 << 13,
+ EG_CF_ALLOC_EXPORT_WORD0__RW_GPR_shift = 15,//7 bits
+ EG_CF_ALLOC_EXPORT_WORD0__RW_GPR_mask = 0x7F << 15,
+ EG_CF_ALLOC_EXPORT_WORD0__RW_REL_shift = 22,//1 bit
+ EG_CF_ALLOC_EXPORT_WORD0__RW_REL_bit = 1 << 22,
+ EG_CF_ALLOC_EXPORT_WORD0__INDEX_GPR_shift = 23,//7 bits
+ EG_CF_ALLOC_EXPORT_WORD0__INDEX_GPR_mask = 0x7F << 23,
+ EG_CF_ALLOC_EXPORT_WORD0__ELEM_SIZE_shift = 30,//2 bits
+ EG_CF_ALLOC_EXPORT_WORD0__ELEM_SIZE_mask = 0x3 << 30,
+
+ EG_CF_ALLOC_EXPORT_WORD1_BUF__ARRAY_SIZE_shift = 0, //12 bits
+ EG_CF_ALLOC_EXPORT_WORD1_BUF__ARRAY_SIZE_mask = 0xFFF,
+ EG_CF_ALLOC_EXPORT_WORD1_BUF__COMP_MASK_shift = 12, //4 bits
+ EG_CF_ALLOC_EXPORT_WORD1_BUF__COMP_MASK_mask = 0xF << 12,
+
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__SEL_X_shift = 0, //3 bits
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__SEL_X_mask = 0x7,
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__SEL_Y_shift = 3, //3 bits
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__SEL_Y_mask = 0x7 << 3,
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__SEL_Z_shift = 6, //3 bits
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__SEL_Z_mask = 0x7 << 6,
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__SEL_W_shift = 9, //3 bits
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__SEL_W_mask = 0x7 << 9,
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__Resreve_shift = 12,//4 bits
+ EG_CF_ALLOC_EXPORT_WORD1_SWIZ__Resreve_mask = 0xF << 12,
+
+ EG_CF_ALLOC_EXPORT_WORD1__BURST_COUNT_shift = 16, //4 bits
+ EG_CF_ALLOC_EXPORT_WORD1__BURST_COUNT_mask = 0xF << 16,
+ EG_CF_ALLOC_EXPORT_WORD1__VPM_shift = 20, //1 bit
+ EG_CF_ALLOC_EXPORT_WORD1__VPM_bit = 1 << 20,
+ EG_CF_ALLOC_EXPORT_WORD1__EOP_shift = 21, //1 bit
+ EG_CF_ALLOC_EXPORT_WORD1__EOP_bit = 1 << 21,
+ EG_CF_ALLOC_EXPORT_WORD1__CF_INST_shift = 22, //8 bits
+ EG_CF_ALLOC_EXPORT_WORD1__CF_INST_mask = 0xFF << 22,
+ EG_CF_ALLOC_EXPORT_WORD1__MARK_shift = 30, //1 bit
+ EG_CF_ALLOC_EXPORT_WORD1__MARK_bit = 1 << 30,
+ EG_CF_ALLOC_EXPORT_WORD1__BARRIER_shift = 31, //1 bit
+ EG_CF_ALLOC_EXPORT_WORD1__BARRIER_bit = 1 << 31,
+
+ EG_CF_INST_MEM_STREAM0_BUF0 = 64 ,
+ EG_CF_INST_MEM_STREAM0_BUF1 = 65,
+ EG_CF_INST_MEM_STREAM0_BUF2 = 66,
+ EG_CF_INST_MEM_STREAM0_BUF3 = 67,
+ EG_CF_INST_MEM_STREAM1_BUF0 = 68,
+ EG_CF_INST_MEM_STREAM1_BUF1 = 69,
+ EG_CF_INST_MEM_STREAM1_BUF2 = 70,
+ EG_CF_INST_MEM_STREAM1_BUF3 = 71,
+ EG_CF_INST_MEM_STREAM2_BUF0 = 72,
+ EG_CF_INST_MEM_STREAM2_BUF1 = 73,
+ EG_CF_INST_MEM_STREAM2_BUF2 = 74,
+ EG_CF_INST_MEM_STREAM2_BUF3 = 75,
+ EG_CF_INST_MEM_STREAM3_BUF0 = 76,
+ EG_CF_INST_MEM_STREAM3_BUF1 = 77,
+ EG_CF_INST_MEM_STREAM3_BUF2 = 78,
+ EG_CF_INST_MEM_STREAM3_BUF3 = 79,
+ EG_CF_INST_MEM_WR_SCRATCH = 80,
+ EG_CF_INST_MEM_RING = 82,
+ EG_CF_INST_EXPORT = 83,
+ EG_CF_INST_EXPORT_DONE = 84,
+ EG_CF_INST_MEM_EXPORT = 85,
+ EG_CF_INST_MEM_RAT = 86,
+ EG_CF_INST_MEM_RAT_CACHELESS = 87,
+ EG_CF_INST_MEM_RING1 = 88,
+ EG_CF_INST_MEM_RING2 = 89,
+ EG_CF_INST_MEM_RING3 = 90,
+ EG_CF_INST_MEM_EXPORT_COMBINED = 91,
+ EG_CF_INST_MEM_RAT_COMBINED_CACHELESS = 92,
+
+ EG_EXPORT_PIXEL = 0,
+ EG_EXPORT_WRITE = 0,
+ EG_EXPORT_POS = 1,
+ EG_EXPORT_WRITE_IND = 1,
+ EG_EXPORT_PARAM = 2,
+ EG_EXPORT_WRITE_ACK = 2,
+ EG_EXPORT_WRITE_IND_ACK = 3,
+
+ /* PS interp param source */
+ EG_ALU_SRC_PARAM_BASE = 0x000001c0,
+ EG_ALU_SRC_PARAM_SIZE = 0x00000021,
+};
+
+#endif //_EVERGREEN_SQ_H_
+
+
diff --git a/src/mesa/drivers/dri/r600/evergreen_state.c b/src/mesa/drivers/dri/r600/evergreen_state.c
new file mode 100644
index 00000000000..931478caa5a
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_state.c
@@ -0,0 +1,1878 @@
+/*
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "main/enums.h"
+#include "main/macros.h"
+#include "main/context.h"
+#include "main/dd.h"
+#include "main/simple_list.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_pipeline.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "main/api_arrayelt.h"
+#include "main/framebuffer.h"
+#include "drivers/common/meta.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+
+#include "vbo/vbo.h"
+
+#include "r600_context.h"
+
+#include "evergreen_state.h"
+#include "evergreen_diff.h"
+#include "evergreen_vertprog.h"
+#include "evergreen_fragprog.h"
+#include "evergreen_tex.h"
+
+void evergreenUpdateStateParameters(GLcontext * ctx, GLuint new_state); //same
+
+void evergreenUpdateShaders(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+
+ /* should only happenen once, just after context is created */
+ /* TODO: shouldn't we fallback to sw here? */
+ if (!ctx->FragmentProgram._Current) {
+ fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
+ return;
+ }
+
+ evergreenSelectFragmentShader(ctx);
+
+ evergreenSelectVertexShader(ctx);
+ evergreenUpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+ context->radeon.NewGLState = 0;
+}
+
+void evergreeUpdateShaders(GLcontext * ctx)
+{
+ context_t *context = R700_CONTEXT(ctx);
+
+ /* should only happenen once, just after context is created */
+ /* TODO: shouldn't we fallback to sw here? */
+ if (!ctx->FragmentProgram._Current) {
+ fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
+ return;
+ }
+
+ evergreenSelectFragmentShader(ctx);
+
+ evergreenSelectVertexShader(ctx);
+ evergreenUpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+ context->radeon.NewGLState = 0;
+}
+
+/*
+ * To correctly position primitives:
+ */
+void evergreenUpdateViewportOffset(GLcontext * ctx) //------------------
+{
+ context_t *context = R700_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ __DRIdrawable *dPriv = radeon_get_drawable(&context->radeon);
+ GLfloat xoffset = (GLfloat) dPriv->x;
+ GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h;
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ int id = 0;
+
+ GLfloat tx = v[MAT_TX] + xoffset;
+ GLfloat ty = (-v[MAT_TY]) + yoffset;
+
+ if (evergreen->viewport[id].PA_CL_VPORT_XOFFSET.f32All != tx ||
+ evergreen->viewport[id].PA_CL_VPORT_YOFFSET.f32All != ty) {
+ /* Note: this should also modify whatever data the context reset
+ * code uses...
+ */
+ EVERGREEN_STATECHANGE(context, pa);
+ evergreen->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
+ evergreen->viewport[id].PA_CL_VPORT_YOFFSET.f32All = ty;
+ }
+
+ radeonUpdateScissor(ctx);
+}
+
+void evergreenUpdateStateParameters(GLcontext * ctx, GLuint new_state) //same
+{
+ struct evergreen_fragment_program *fp =
+ (struct evergreen_fragment_program *)ctx->FragmentProgram._Current;
+ struct gl_program_parameter_list *paramList;
+
+ if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)))
+ return;
+
+ if (!ctx->FragmentProgram._Current || !fp)
+ return;
+
+ paramList = ctx->FragmentProgram._Current->Base.Parameters;
+
+ if (!paramList)
+ return;
+
+ _mesa_load_state_parameters(ctx, paramList);
+
+}
+
+/**
+ * Called by Mesa after an internal state update.
+ */
+static void evergreenInvalidateState(GLcontext * ctx, GLuint new_state) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ _swrast_InvalidateState(ctx, new_state);
+ _swsetup_InvalidateState(ctx, new_state);
+ _vbo_InvalidateState(ctx, new_state);
+ _tnl_InvalidateState(ctx, new_state);
+ _ae_invalidate_state(ctx, new_state);
+
+ if (new_state & _NEW_BUFFERS) {
+ _mesa_update_framebuffer(ctx);
+ /* this updates the DrawBuffer's Width/Height if it's a FBO */
+ _mesa_update_draw_buffer_bounds(ctx);
+
+ EVERGREEN_STATECHANGE(context, cb);
+ EVERGREEN_STATECHANGE(context, db);
+ }
+
+ if (new_state & (_NEW_LIGHT)) {
+ EVERGREEN_STATECHANGE(context, pa);
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION)
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, PROVOKING_VTX_LAST_bit);
+ else
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, PROVOKING_VTX_LAST_bit);
+ }
+
+ evergreenUpdateStateParameters(ctx, new_state);
+
+ EVERGREEN_STATECHANGE(context, pa);
+ EVERGREEN_STATECHANGE(context, spi);
+
+ if(GL_TRUE == evergreen->bEnablePerspective)
+ {
+ /* Do scale XY and Z by 1/W0 for perspective correction on pos. For orthogonal case, set both to one. */
+ CLEARbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_XY_FMT_bit);
+ CLEARbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_Z_FMT_bit);
+
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_W0_FMT_bit);
+
+ SETbit(evergreen->SPI_PS_IN_CONTROL_0.u32All, PERSP_GRADIENT_ENA_bit);
+ CLEARbit(evergreen->SPI_PS_IN_CONTROL_0.u32All, LINEAR_GRADIENT_ENA_bit);
+
+ SETfield(evergreen->SPI_BARYC_CNTL.u32All, 1,
+ EG_SPI_BARYC_CNTL__PERSP_CENTROID_ENA_shift,
+ EG_SPI_BARYC_CNTL__PERSP_CENTROID_ENA_mask);
+ }
+ else
+ {
+ /* For orthogonal case. */
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_XY_FMT_bit);
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_Z_FMT_bit);
+
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_W0_FMT_bit);
+
+ CLEARbit(evergreen->SPI_PS_IN_CONTROL_0.u32All, PERSP_GRADIENT_ENA_bit);
+ SETbit(evergreen->SPI_PS_IN_CONTROL_0.u32All, LINEAR_GRADIENT_ENA_bit);
+
+ SETfield(evergreen->SPI_BARYC_CNTL.u32All, 1,
+ EG_SPI_BARYC_CNTL__LINEAR_CENTROID_ENA_shift,
+ EG_SPI_BARYC_CNTL__LINEAR_CENTROID_ENA_mask);
+ }
+
+ context->radeon.NewGLState |= new_state;
+}
+
+static void evergreenSetAlphaState(GLcontext * ctx) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ uint32_t alpha_func = REF_ALWAYS;
+ GLboolean really_enabled = ctx->Color.AlphaEnabled;
+
+ EVERGREEN_STATECHANGE(context, sx);
+
+ switch (ctx->Color.AlphaFunc) {
+ case GL_NEVER:
+ alpha_func = REF_NEVER;
+ break;
+ case GL_LESS:
+ alpha_func = REF_LESS;
+ break;
+ case GL_EQUAL:
+ alpha_func = REF_EQUAL;
+ break;
+ case GL_LEQUAL:
+ alpha_func = REF_LEQUAL;
+ break;
+ case GL_GREATER:
+ alpha_func = REF_GREATER;
+ break;
+ case GL_NOTEQUAL:
+ alpha_func = REF_NOTEQUAL;
+ break;
+ case GL_GEQUAL:
+ alpha_func = REF_GEQUAL;
+ break;
+ case GL_ALWAYS:
+ /*alpha_func = REF_ALWAYS; */
+ really_enabled = GL_FALSE;
+ break;
+ }
+
+ if (really_enabled) {
+ SETfield(evergreen->SX_ALPHA_TEST_CONTROL.u32All, alpha_func,
+ ALPHA_FUNC_shift, ALPHA_FUNC_mask);
+ SETbit(evergreen->SX_ALPHA_TEST_CONTROL.u32All, ALPHA_TEST_ENABLE_bit);
+ evergreen->SX_ALPHA_REF.f32All = ctx->Color.AlphaRef;
+ } else {
+ CLEARbit(evergreen->SX_ALPHA_TEST_CONTROL.u32All, ALPHA_TEST_ENABLE_bit);
+ }
+}
+
+static void evergreenAlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) //same
+{
+ (void)func;
+ (void)ref;
+ evergreenSetAlphaState(ctx);
+}
+
+static void evergreenBlendColor(GLcontext * ctx, const GLfloat cf[4]) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, cb);
+
+ evergreen->CB_BLEND_RED.f32All = cf[0];
+ evergreen->CB_BLEND_GREEN.f32All = cf[1];
+ evergreen->CB_BLEND_BLUE.f32All = cf[2];
+ evergreen->CB_BLEND_ALPHA.f32All = cf[3];
+}
+
+static int evergreenblend_factor(GLenum factor, GLboolean is_src) //same
+{
+ switch (factor) {
+ case GL_ZERO:
+ return BLEND_ZERO;
+ break;
+ case GL_ONE:
+ return BLEND_ONE;
+ break;
+ case GL_DST_COLOR:
+ return BLEND_DST_COLOR;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ return BLEND_ONE_MINUS_DST_COLOR;
+ break;
+ case GL_SRC_COLOR:
+ return BLEND_SRC_COLOR;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ return BLEND_ONE_MINUS_SRC_COLOR;
+ break;
+ case GL_SRC_ALPHA:
+ return BLEND_SRC_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ return BLEND_ONE_MINUS_SRC_ALPHA;
+ break;
+ case GL_DST_ALPHA:
+ return BLEND_DST_ALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ return BLEND_ONE_MINUS_DST_ALPHA;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ return (is_src) ? BLEND_SRC_ALPHA_SATURATE : BLEND_ZERO;
+ break;
+ case GL_CONSTANT_COLOR:
+ return BLEND_CONSTANT_COLOR;
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ return BLEND_ONE_MINUS_CONSTANT_COLOR;
+ break;
+ case GL_CONSTANT_ALPHA:
+ return BLEND_CONSTANT_ALPHA;
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ return BLEND_ONE_MINUS_CONSTANT_ALPHA;
+ break;
+ default:
+ fprintf(stderr, "unknown blend factor %x\n", factor);
+ return (is_src) ? BLEND_ONE : BLEND_ZERO;
+ break;
+ }
+}
+
+static void evergreenSetBlendState(GLcontext * ctx) //diff : CB_COLOR_CONTROL, CB_BLEND0_CONTROL bits
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ uint32_t blend_reg = 0, eqn, eqnA;
+
+ EVERGREEN_STATECHANGE(context, cb);
+
+ if (RGBA_LOGICOP_ENABLED(ctx) || !ctx->Color.BlendEnabled) {
+ SETfield(blend_reg,
+ BLEND_ONE, COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
+ SETfield(blend_reg,
+ BLEND_ZERO, COLOR_DESTBLEND_shift, COLOR_DESTBLEND_mask);
+ SETfield(blend_reg,
+ COMB_DST_PLUS_SRC, COLOR_COMB_FCN_shift, COLOR_COMB_FCN_mask);
+ SETfield(blend_reg,
+ BLEND_ONE, ALPHA_SRCBLEND_shift, ALPHA_SRCBLEND_mask);
+ SETfield(blend_reg,
+ BLEND_ZERO, ALPHA_DESTBLEND_shift, ALPHA_DESTBLEND_mask);
+ SETfield(blend_reg,
+ COMB_DST_PLUS_SRC, ALPHA_COMB_FCN_shift, ALPHA_COMB_FCN_mask);
+ //if (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_R600)
+ // evergreen->CB_BLEND_CONTROL.u32All = blend_reg;
+ //else
+ evergreen->CB_BLEND0_CONTROL.u32All = blend_reg;
+ return;
+ }
+
+ SETfield(blend_reg,
+ evergreenblend_factor(ctx->Color.BlendSrcRGB, GL_TRUE),
+ COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
+ SETfield(blend_reg,
+ evergreenblend_factor(ctx->Color.BlendDstRGB, GL_FALSE),
+ COLOR_DESTBLEND_shift, COLOR_DESTBLEND_mask);
+
+ switch (ctx->Color.BlendEquationRGB) {
+ case GL_FUNC_ADD:
+ eqn = COMB_DST_PLUS_SRC;
+ break;
+ case GL_FUNC_SUBTRACT:
+ eqn = COMB_SRC_MINUS_DST;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ eqn = COMB_DST_MINUS_SRC;
+ break;
+ case GL_MIN:
+ eqn = COMB_MIN_DST_SRC;
+ SETfield(blend_reg,
+ BLEND_ONE,
+ COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
+ SETfield(blend_reg,
+ BLEND_ONE,
+ COLOR_DESTBLEND_shift, COLOR_DESTBLEND_mask);
+ break;
+ case GL_MAX:
+ eqn = COMB_MAX_DST_SRC;
+ SETfield(blend_reg,
+ BLEND_ONE,
+ COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
+ SETfield(blend_reg,
+ BLEND_ONE,
+ COLOR_DESTBLEND_shift, COLOR_DESTBLEND_mask);
+ break;
+
+ default:
+ fprintf(stderr,
+ "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
+ __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB);
+ return;
+ }
+ SETfield(blend_reg,
+ eqn, COLOR_COMB_FCN_shift, COLOR_COMB_FCN_mask);
+
+ SETfield(blend_reg,
+ evergreenblend_factor(ctx->Color.BlendSrcA, GL_TRUE),
+ ALPHA_SRCBLEND_shift, ALPHA_SRCBLEND_mask);
+ SETfield(blend_reg,
+ evergreenblend_factor(ctx->Color.BlendDstA, GL_FALSE),
+ ALPHA_DESTBLEND_shift, ALPHA_DESTBLEND_mask);
+
+ switch (ctx->Color.BlendEquationA) {
+ case GL_FUNC_ADD:
+ eqnA = COMB_DST_PLUS_SRC;
+ break;
+ case GL_FUNC_SUBTRACT:
+ eqnA = COMB_SRC_MINUS_DST;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ eqnA = COMB_DST_MINUS_SRC;
+ break;
+ case GL_MIN:
+ eqnA = COMB_MIN_DST_SRC;
+ SETfield(blend_reg,
+ BLEND_ONE,
+ ALPHA_SRCBLEND_shift, ALPHA_SRCBLEND_mask);
+ SETfield(blend_reg,
+ BLEND_ONE,
+ ALPHA_DESTBLEND_shift, ALPHA_DESTBLEND_mask);
+ break;
+ case GL_MAX:
+ eqnA = COMB_MAX_DST_SRC;
+ SETfield(blend_reg,
+ BLEND_ONE,
+ ALPHA_SRCBLEND_shift, ALPHA_SRCBLEND_mask);
+ SETfield(blend_reg,
+ BLEND_ONE,
+ ALPHA_DESTBLEND_shift, ALPHA_DESTBLEND_mask);
+ break;
+ default:
+ fprintf(stderr,
+ "[%s:%u] Invalid A blend equation (0x%04x).\n",
+ __FUNCTION__, __LINE__, ctx->Color.BlendEquationA);
+ return;
+ }
+
+ SETfield(blend_reg,
+ eqnA, ALPHA_COMB_FCN_shift, ALPHA_COMB_FCN_mask);
+
+ SETbit(blend_reg, SEPARATE_ALPHA_BLEND_bit);
+
+ SETbit(blend_reg, EG_CB_BLENDX_CONTROL_ENABLE_bit);
+
+ evergreen->CB_BLEND0_CONTROL.u32All = blend_reg;
+}
+
+static void evergreenBlendEquationSeparate(GLcontext * ctx,
+ GLenum modeRGB, GLenum modeA) //same
+{
+ evergreenSetBlendState(ctx);
+}
+
+static void evergreenBlendFuncSeparate(GLcontext * ctx,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA) //same
+{
+ evergreenSetBlendState(ctx);
+}
+
+static GLuint evergreen_translate_logicop(GLenum logicop) //same
+{
+ switch (logicop) {
+ case GL_CLEAR:
+ return 0x00;
+ case GL_SET:
+ return 0xff;
+ case GL_COPY:
+ return 0xcc;
+ case GL_COPY_INVERTED:
+ return 0x33;
+ case GL_NOOP:
+ return 0xaa;
+ case GL_INVERT:
+ return 0x55;
+ case GL_AND:
+ return 0x88;
+ case GL_NAND:
+ return 0x77;
+ case GL_OR:
+ return 0xee;
+ case GL_NOR:
+ return 0x11;
+ case GL_XOR:
+ return 0x66;
+ case GL_EQUIV:
+ return 0x99;
+ case GL_AND_REVERSE:
+ return 0x44;
+ case GL_AND_INVERTED:
+ return 0x22;
+ case GL_OR_REVERSE:
+ return 0xdd;
+ case GL_OR_INVERTED:
+ return 0xbb;
+ default:
+ fprintf(stderr, "unknown blend logic operation %x\n", logicop);
+ return 0xcc;
+ }
+}
+
+static void evergreenSetLogicOpState(GLcontext *ctx) //diff : CB_COLOR_CONTROL.ROP3 is actually same bits.
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, cb);
+
+ if (RGBA_LOGICOP_ENABLED(ctx))
+ SETfield(evergreen->CB_COLOR_CONTROL.u32All,
+ evergreen_translate_logicop(ctx->Color.LogicOp),
+ EG_CB_COLOR_CONTROL__ROP3_shift,
+ EG_CB_COLOR_CONTROL__ROP3_mask);
+ else
+ SETfield(evergreen->CB_COLOR_CONTROL.u32All, 0xCC,
+ EG_CB_COLOR_CONTROL__ROP3_shift,
+ EG_CB_COLOR_CONTROL__ROP3_mask);
+}
+
+static void evergreenClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) //same , but PA_CL_UCP_0_ offset diff
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ GLint p;
+ GLint *ip;
+
+ p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
+ ip = (GLint *)ctx->Transform._ClipUserPlane[p];
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ evergreen->ucp[p].PA_CL_UCP_0_X.u32All = ip[0];
+ evergreen->ucp[p].PA_CL_UCP_0_Y.u32All = ip[1];
+ evergreen->ucp[p].PA_CL_UCP_0_Z.u32All = ip[2];
+ evergreen->ucp[p].PA_CL_UCP_0_W.u32All = ip[3];
+}
+
+static void evergreenSetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state) //diff in func calls
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ GLuint p;
+
+ p = cap - GL_CLIP_PLANE0;
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ if (state) {
+ evergreen->PA_CL_CLIP_CNTL.u32All |= (UCP_ENA_0_bit << p);
+ evergreen->ucp[p].enabled = GL_TRUE;
+ evergreenClipPlane(ctx, cap, NULL);
+ } else {
+ evergreen->PA_CL_CLIP_CNTL.u32All &= ~(UCP_ENA_0_bit << p);
+ evergreen->ucp[p].enabled = GL_FALSE;
+ }
+}
+
+static void evergreenSetDBRenderState(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct evergreen_fragment_program *fp =
+ (struct evergreen_fragment_program *)(ctx->FragmentProgram._Current);
+
+ EVERGREEN_STATECHANGE(context, db);
+
+ SETbit(evergreen->DB_SHADER_CONTROL.u32All,
+ DUAL_EXPORT_ENABLE_bit);
+ SETfield(evergreen->DB_SHADER_CONTROL.u32All, EARLY_Z_THEN_LATE_Z,
+ Z_ORDER_shift,
+ Z_ORDER_mask);
+ /* XXX need to enable htile for hiz/s */
+ SETfield(evergreen->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE,
+ FORCE_HIZ_ENABLE_shift,
+ FORCE_HIZ_ENABLE_mask);
+ SETfield(evergreen->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE,
+ FORCE_HIS_ENABLE0_shift,
+ FORCE_HIS_ENABLE0_mask);
+ SETfield(evergreen->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE,
+ FORCE_HIS_ENABLE1_shift,
+ FORCE_HIS_ENABLE1_mask);
+
+ if (context->radeon.query.current)
+ {
+ SETbit(evergreen->DB_RENDER_OVERRIDE.u32All, NOOP_CULL_DISABLE_bit);
+ SETbit(evergreen->DB_COUNT_CONTROL.u32All,
+ EG_DB_COUNT_CONTROL__PERFECT_ZPASS_COUNTS_bit);
+ }
+ else
+ {
+ CLEARbit(evergreen->DB_RENDER_OVERRIDE.u32All, NOOP_CULL_DISABLE_bit);
+ CLEARbit(evergreen->DB_COUNT_CONTROL.u32All,
+ EG_DB_COUNT_CONTROL__PERFECT_ZPASS_COUNTS_bit);
+ }
+
+ if (fp)
+ {
+ if (fp->r700Shader.killIsUsed)
+ {
+ SETbit(evergreen->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
+ }
+ else
+ {
+ CLEARbit(evergreen->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
+ }
+
+ if (fp->r700Shader.depthIsExported)
+ {
+ SETbit(evergreen->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
+ }
+ else
+ {
+ CLEARbit(evergreen->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
+ }
+ }
+}
+
+void evergreenUpdateShaderStates(GLcontext * ctx)
+{
+ evergreenSetDBRenderState(ctx);
+ evergreenUpdateTextureState(ctx);
+}
+
+static void evergreenSetDepthState(GLcontext * ctx) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, db);
+
+ if (ctx->Depth.Test)
+ {
+ SETbit(evergreen->DB_DEPTH_CONTROL.u32All, Z_ENABLE_bit);
+ if (ctx->Depth.Mask)
+ {
+ SETbit(evergreen->DB_DEPTH_CONTROL.u32All, Z_WRITE_ENABLE_bit);
+ }
+ else
+ {
+ CLEARbit(evergreen->DB_DEPTH_CONTROL.u32All, Z_WRITE_ENABLE_bit);
+ }
+
+ switch (ctx->Depth.Func)
+ {
+ case GL_NEVER:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_NEVER,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ case GL_LESS:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_LESS,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ case GL_EQUAL:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_EQUAL,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ case GL_LEQUAL:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_LEQUAL,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ case GL_GREATER:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_GREATER,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ case GL_NOTEQUAL:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_NOTEQUAL,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ case GL_GEQUAL:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_GEQUAL,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ case GL_ALWAYS:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_ALWAYS,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ default:
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_ALWAYS,
+ ZFUNC_shift, ZFUNC_mask);
+ break;
+ }
+ }
+ else
+ {
+ CLEARbit(evergreen->DB_DEPTH_CONTROL.u32All, Z_ENABLE_bit);
+ CLEARbit(evergreen->DB_DEPTH_CONTROL.u32All, Z_WRITE_ENABLE_bit);
+ }
+}
+
+static void evergreenSetStencilState(GLcontext * ctx, GLboolean state) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ GLboolean hw_stencil = GL_FALSE;
+
+ if (ctx->DrawBuffer) {
+ struct radeon_renderbuffer *rrbStencil
+ = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
+ hw_stencil = (rrbStencil && rrbStencil->bo);
+ }
+
+ if (hw_stencil) {
+ EVERGREEN_STATECHANGE(context, db);
+ if (state) {
+ SETbit(evergreen->DB_DEPTH_CONTROL.u32All, STENCIL_ENABLE_bit);
+ SETbit(evergreen->DB_DEPTH_CONTROL.u32All, BACKFACE_ENABLE_bit);
+ } else
+ CLEARbit(evergreen->DB_DEPTH_CONTROL.u32All, STENCIL_ENABLE_bit);
+ }
+}
+
+static void evergreenUpdateCulling(GLcontext * ctx) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, FACE_bit);
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_FRONT_bit);
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_BACK_bit);
+
+ if (ctx->Polygon.CullFlag)
+ {
+ switch (ctx->Polygon.CullFaceMode)
+ {
+ case GL_FRONT:
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_FRONT_bit);
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_BACK_bit);
+ break;
+ case GL_BACK:
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_FRONT_bit);
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_BACK_bit);
+ break;
+ case GL_FRONT_AND_BACK:
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_FRONT_bit);
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_BACK_bit);
+ break;
+ default:
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_FRONT_bit);
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, CULL_BACK_bit);
+ break;
+ }
+ }
+
+ switch (ctx->Polygon.FrontFace)
+ {
+ case GL_CW:
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, FACE_bit);
+ break;
+ case GL_CCW:
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, FACE_bit);
+ break;
+ default:
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, FACE_bit); /* default: ccw */
+ break;
+ }
+
+ /* Winding is inverted when rendering to FBO */
+ if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
+ evergreen->PA_SU_SC_MODE_CNTL.u32All ^= FACE_bit;
+}
+
+static void evergreenSetPolygonOffsetState(GLcontext * ctx, GLboolean state) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ if (state) {
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_FRONT_ENABLE_bit);
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_BACK_ENABLE_bit);
+ SETbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_PARA_ENABLE_bit);
+ } else {
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_FRONT_ENABLE_bit);
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_BACK_ENABLE_bit);
+ CLEARbit(evergreen->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_PARA_ENABLE_bit);
+ }
+}
+
+static void evergreenUpdateLineStipple(GLcontext * ctx) //diff
+{
+ /* TODO */
+}
+
+void evergreenSetScissor(context_t *context) //diff
+{
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ unsigned x1, y1, x2, y2;
+ int id = 0;
+ struct radeon_renderbuffer *rrb;
+
+ rrb = radeon_get_colorbuffer(&context->radeon);
+ if (!rrb || !rrb->bo) {
+ return;
+ }
+ if (context->radeon.state.scissor.enabled) {
+ x1 = context->radeon.state.scissor.rect.x1;
+ y1 = context->radeon.state.scissor.rect.y1;
+ x2 = context->radeon.state.scissor.rect.x2;
+ y2 = context->radeon.state.scissor.rect.y2;
+ /* r600 has exclusive BR scissors */
+ if (context->radeon.radeonScreen->kernel_mm) {
+ x2++;
+ y2++;
+ }
+ } else {
+ if (context->radeon.radeonScreen->driScreen->dri2.enabled) {
+ x1 = 0;
+ y1 = 0;
+ x2 = rrb->base.Width;
+ y2 = rrb->base.Height;
+ } else {
+ x1 = rrb->dPriv->x;
+ y1 = rrb->dPriv->y;
+ x2 = rrb->dPriv->x + rrb->dPriv->w;
+ y2 = rrb->dPriv->y + rrb->dPriv->h;
+ }
+ }
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ /* screen */
+ /* TODO : check WINDOW_OFFSET_DISABLE */
+ //SETbit(evergreen->PA_SC_SCREEN_SCISSOR_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
+ SETfield(evergreen->PA_SC_SCREEN_SCISSOR_TL.u32All, x1,
+ PA_SC_SCREEN_SCISSOR_TL__TL_X_shift, EG_PA_SC_SCREEN_SCISSOR_TL__TL_X_mask);
+ SETfield(evergreen->PA_SC_SCREEN_SCISSOR_TL.u32All, y1,
+ PA_SC_SCREEN_SCISSOR_TL__TL_Y_shift, EG_PA_SC_SCREEN_SCISSOR_TL__TL_Y_mask);
+
+ SETfield(evergreen->PA_SC_SCREEN_SCISSOR_BR.u32All, x2,
+ PA_SC_SCREEN_SCISSOR_BR__BR_X_shift, EG_PA_SC_SCREEN_SCISSOR_BR__BR_X_mask);
+ SETfield(evergreen->PA_SC_SCREEN_SCISSOR_BR.u32All, y2,
+ PA_SC_SCREEN_SCISSOR_BR__BR_Y_shift, EG_PA_SC_SCREEN_SCISSOR_BR__BR_Y_mask);
+
+ /* window */
+ SETbit(evergreen->PA_SC_WINDOW_SCISSOR_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
+ SETfield(evergreen->PA_SC_WINDOW_SCISSOR_TL.u32All, x1,
+ PA_SC_WINDOW_SCISSOR_TL__TL_X_shift, EG_PA_SC_WINDOW_SCISSOR_TL__TL_X_mask);
+ SETfield(evergreen->PA_SC_WINDOW_SCISSOR_TL.u32All, y1,
+ PA_SC_WINDOW_SCISSOR_TL__TL_Y_shift, EG_PA_SC_WINDOW_SCISSOR_TL__TL_Y_mask);
+
+ SETfield(evergreen->PA_SC_WINDOW_SCISSOR_BR.u32All, x2,
+ PA_SC_WINDOW_SCISSOR_BR__BR_X_shift, EG_PA_SC_WINDOW_SCISSOR_BR__BR_X_mask);
+ SETfield(evergreen->PA_SC_WINDOW_SCISSOR_BR.u32All, y2,
+ PA_SC_WINDOW_SCISSOR_BR__BR_Y_shift, EG_PA_SC_WINDOW_SCISSOR_BR__BR_Y_mask);
+
+
+ SETfield(evergreen->PA_SC_CLIPRECT_0_TL.u32All, x1,
+ PA_SC_CLIPRECT_0_TL__TL_X_shift, EG_PA_SC_CLIPRECT_0_TL__TL_X_mask);
+ SETfield(evergreen->PA_SC_CLIPRECT_0_TL.u32All, y1,
+ PA_SC_CLIPRECT_0_TL__TL_Y_shift, EG_PA_SC_CLIPRECT_0_TL__TL_Y_mask);
+ SETfield(evergreen->PA_SC_CLIPRECT_0_BR.u32All, x2,
+ PA_SC_CLIPRECT_0_BR__BR_X_shift, EG_PA_SC_CLIPRECT_0_BR__BR_X_mask);
+ SETfield(evergreen->PA_SC_CLIPRECT_0_BR.u32All, y2,
+ PA_SC_CLIPRECT_0_BR__BR_Y_shift, EG_PA_SC_CLIPRECT_0_BR__BR_Y_mask);
+
+ evergreen->PA_SC_CLIPRECT_1_TL.u32All = evergreen->PA_SC_CLIPRECT_0_TL.u32All;
+ evergreen->PA_SC_CLIPRECT_1_BR.u32All = evergreen->PA_SC_CLIPRECT_0_BR.u32All;
+ evergreen->PA_SC_CLIPRECT_2_TL.u32All = evergreen->PA_SC_CLIPRECT_0_TL.u32All;
+ evergreen->PA_SC_CLIPRECT_2_BR.u32All = evergreen->PA_SC_CLIPRECT_0_BR.u32All;
+ evergreen->PA_SC_CLIPRECT_3_TL.u32All = evergreen->PA_SC_CLIPRECT_0_TL.u32All;
+ evergreen->PA_SC_CLIPRECT_3_BR.u32All = evergreen->PA_SC_CLIPRECT_0_BR.u32All;
+
+ /* more....2d clip */
+ SETbit(evergreen->PA_SC_GENERIC_SCISSOR_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
+ SETfield(evergreen->PA_SC_GENERIC_SCISSOR_TL.u32All, x1,
+ PA_SC_GENERIC_SCISSOR_TL__TL_X_shift, EG_PA_SC_GENERIC_SCISSOR_TL__TL_X_mask);
+ SETfield(evergreen->PA_SC_GENERIC_SCISSOR_TL.u32All, y1,
+ PA_SC_GENERIC_SCISSOR_TL__TL_Y_shift, EG_PA_SC_GENERIC_SCISSOR_TL__TL_Y_mask);
+ SETfield(evergreen->PA_SC_GENERIC_SCISSOR_BR.u32All, x2,
+ PA_SC_GENERIC_SCISSOR_BR__BR_X_shift, EG_PA_SC_GENERIC_SCISSOR_BR__BR_X_mask);
+ SETfield(evergreen->PA_SC_GENERIC_SCISSOR_BR.u32All, y2,
+ PA_SC_GENERIC_SCISSOR_BR__BR_Y_shift, EG_PA_SC_GENERIC_SCISSOR_BR__BR_Y_mask);
+
+ SETbit(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
+ SETfield(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_TL.u32All, x1,
+ PA_SC_VPORT_SCISSOR_0_TL__TL_X_shift, EG_PA_SC_VPORT_SCISSOR_0_TL__TL_X_mask);
+ SETfield(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_TL.u32All, y1,
+ PA_SC_VPORT_SCISSOR_0_TL__TL_Y_shift, EG_PA_SC_VPORT_SCISSOR_0_TL__TL_Y_mask);
+ SETfield(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_BR.u32All, x2,
+ PA_SC_VPORT_SCISSOR_0_BR__BR_X_shift, EG_PA_SC_VPORT_SCISSOR_0_BR__BR_X_mask);
+ SETfield(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_BR.u32All, y2,
+ PA_SC_VPORT_SCISSOR_0_BR__BR_Y_shift, EG_PA_SC_VPORT_SCISSOR_0_BR__BR_Y_mask);
+
+ id = 1;
+ SETbit(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
+ SETfield(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_TL.u32All, x1,
+ PA_SC_VPORT_SCISSOR_0_TL__TL_X_shift, EG_PA_SC_VPORT_SCISSOR_0_TL__TL_X_mask);
+ SETfield(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_TL.u32All, y1,
+ PA_SC_VPORT_SCISSOR_0_TL__TL_Y_shift, EG_PA_SC_VPORT_SCISSOR_0_TL__TL_Y_mask);
+ SETfield(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_BR.u32All, x2,
+ PA_SC_VPORT_SCISSOR_0_BR__BR_X_shift, EG_PA_SC_VPORT_SCISSOR_0_BR__BR_X_mask);
+ SETfield(evergreen->viewport[id].PA_SC_VPORT_SCISSOR_0_BR.u32All, y2,
+ PA_SC_VPORT_SCISSOR_0_BR__BR_Y_shift, EG_PA_SC_VPORT_SCISSOR_0_BR__BR_Y_mask);
+
+ evergreen->viewport[id].enabled = GL_TRUE;
+}
+
+static void evergreenUpdateWindow(GLcontext * ctx, int id) //diff in calling evergreenSetScissor
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ __DRIdrawable *dPriv = radeon_get_drawable(&context->radeon);
+ GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
+ GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+ const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
+ const GLboolean render_to_fbo = (ctx->DrawBuffer->Name != 0);
+ GLfloat y_scale, y_bias;
+
+ if (render_to_fbo) {
+ y_scale = 1.0;
+ y_bias = 0;
+ } else {
+ y_scale = -1.0;
+ y_bias = yoffset;
+ }
+
+ GLfloat sx = v[MAT_SX];
+ GLfloat tx = v[MAT_TX] + xoffset;
+ GLfloat sy = v[MAT_SY] * y_scale;
+ GLfloat ty = (v[MAT_TY] * y_scale) + y_bias;
+ GLfloat sz = v[MAT_SZ] * depthScale;
+ GLfloat tz = v[MAT_TZ] * depthScale;
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+
+ evergreen->viewport[id].PA_CL_VPORT_XSCALE.f32All = sx;
+ evergreen->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
+
+ evergreen->viewport[id].PA_CL_VPORT_YSCALE.f32All = sy;
+ evergreen->viewport[id].PA_CL_VPORT_YOFFSET.f32All = ty;
+
+ evergreen->viewport[id].PA_CL_VPORT_ZSCALE.f32All = sz;
+ evergreen->viewport[id].PA_CL_VPORT_ZOFFSET.f32All = tz;
+
+ if (ctx->Transform.DepthClamp) {
+ evergreen->viewport[id].PA_SC_VPORT_ZMIN_0.f32All = MIN2(ctx->Viewport.Near, ctx->Viewport.Far);
+ evergreen->viewport[id].PA_SC_VPORT_ZMAX_0.f32All = MAX2(ctx->Viewport.Near, ctx->Viewport.Far);
+ SETbit(evergreen->PA_CL_CLIP_CNTL.u32All, ZCLIP_NEAR_DISABLE_bit);
+ SETbit(evergreen->PA_CL_CLIP_CNTL.u32All, ZCLIP_FAR_DISABLE_bit);
+ } else {
+ evergreen->viewport[id].PA_SC_VPORT_ZMIN_0.f32All = 0.0;
+ evergreen->viewport[id].PA_SC_VPORT_ZMAX_0.f32All = 1.0;
+ CLEARbit(evergreen->PA_CL_CLIP_CNTL.u32All, ZCLIP_NEAR_DISABLE_bit);
+ CLEARbit(evergreen->PA_CL_CLIP_CNTL.u32All, ZCLIP_FAR_DISABLE_bit);
+ }
+
+ evergreen->viewport[id].enabled = GL_TRUE;
+
+ evergreenSetScissor(context);
+}
+
+static void evergreenEnable(GLcontext * ctx, GLenum cap, GLboolean state) //diff in func calls
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+
+ switch (cap) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ /* empty */
+ break;
+ case GL_FOG:
+ /* empty */
+ break;
+ case GL_ALPHA_TEST:
+ evergreenSetAlphaState(ctx);
+ break;
+ case GL_COLOR_LOGIC_OP:
+ evergreenSetLogicOpState(ctx);
+ /* fall-through, because logic op overrides blending */
+ case GL_BLEND:
+ evergreenSetBlendState(ctx);
+ break;
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ evergreenSetClipPlaneState(ctx, cap, state);
+ break;
+ case GL_DEPTH_TEST:
+ evergreenSetDepthState(ctx);
+ break;
+ case GL_STENCIL_TEST:
+ evergreenSetStencilState(ctx, state);
+ break;
+ case GL_CULL_FACE:
+ evergreenUpdateCulling(ctx);
+ break;
+ case GL_POLYGON_OFFSET_POINT:
+ case GL_POLYGON_OFFSET_LINE:
+ case GL_POLYGON_OFFSET_FILL:
+ evergreenSetPolygonOffsetState(ctx, state);
+ break;
+ case GL_SCISSOR_TEST:
+ radeon_firevertices(&context->radeon);
+ context->radeon.state.scissor.enabled = state;
+ radeonUpdateScissor(ctx);
+ break;
+ case GL_LINE_STIPPLE:
+ evergreenUpdateLineStipple(ctx);
+ break;
+ case GL_DEPTH_CLAMP:
+ evergreenUpdateWindow(ctx, 0);
+ break;
+ default:
+ break;
+ }
+
+}
+
+static void evergreenColorMask(GLcontext * ctx,
+ GLboolean r, GLboolean g, GLboolean b, GLboolean a) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ unsigned int mask = ((r ? 1 : 0) |
+ (g ? 2 : 0) |
+ (b ? 4 : 0) |
+ (a ? 8 : 0));
+
+ if (mask != evergreen->CB_TARGET_MASK.u32All) {
+ EVERGREEN_STATECHANGE(context, cb);
+ SETfield(evergreen->CB_TARGET_MASK.u32All, mask, TARGET0_ENABLE_shift, TARGET0_ENABLE_mask);
+ }
+}
+
+static void evergreenDepthFunc(GLcontext * ctx, GLenum func) //same
+{
+ evergreenSetDepthState(ctx);
+}
+
+static void evergreenDepthMask(GLcontext * ctx, GLboolean mask) //same
+{
+ evergreenSetDepthState(ctx);
+}
+
+static void evergreenCullFace(GLcontext * ctx, GLenum mode) //same
+{
+ evergreenUpdateCulling(ctx);
+}
+
+static void evergreenFogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) //same
+{
+}
+
+static void evergreenUpdatePolygonMode(GLcontext * ctx) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, X_DISABLE_POLY_MODE, POLY_MODE_shift, POLY_MODE_mask);
+
+ /* Only do something if a polygon mode is wanted, default is GL_FILL */
+ if (ctx->Polygon.FrontMode != GL_FILL ||
+ ctx->Polygon.BackMode != GL_FILL) {
+ GLenum f, b;
+
+ /* Handle GL_CW (clock wise and GL_CCW (counter clock wise)
+ * correctly by selecting the correct front and back face
+ */
+ f = ctx->Polygon.FrontMode;
+ b = ctx->Polygon.BackMode;
+
+ /* Enable polygon mode */
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, X_DUAL_MODE, POLY_MODE_shift, POLY_MODE_mask);
+
+ switch (f) {
+ case GL_LINE:
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, X_DRAW_LINES,
+ POLYMODE_FRONT_PTYPE_shift, POLYMODE_FRONT_PTYPE_mask);
+ break;
+ case GL_POINT:
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, X_DRAW_POINTS,
+ POLYMODE_FRONT_PTYPE_shift, POLYMODE_FRONT_PTYPE_mask);
+ break;
+ case GL_FILL:
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, X_DRAW_TRIANGLES,
+ POLYMODE_FRONT_PTYPE_shift, POLYMODE_FRONT_PTYPE_mask);
+ break;
+ }
+
+ switch (b) {
+ case GL_LINE:
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, X_DRAW_LINES,
+ POLYMODE_BACK_PTYPE_shift, POLYMODE_BACK_PTYPE_mask);
+ break;
+ case GL_POINT:
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, X_DRAW_POINTS,
+ POLYMODE_BACK_PTYPE_shift, POLYMODE_BACK_PTYPE_mask);
+ break;
+ case GL_FILL:
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, X_DRAW_TRIANGLES,
+ POLYMODE_BACK_PTYPE_shift, POLYMODE_BACK_PTYPE_mask);
+ break;
+ }
+ }
+}
+
+static void evergreenFrontFace(GLcontext * ctx, GLenum mode) //same
+{
+ evergreenUpdateCulling(ctx);
+ evergreenUpdatePolygonMode(ctx);
+}
+
+static void evergreenShadeModel(GLcontext * ctx, GLenum mode) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, spi);
+
+ /* also need to set/clear FLAT_SHADE bit per param in SPI_PS_INPUT_CNTL_[0-31] */
+ switch (mode) {
+ case GL_FLAT:
+ SETbit(evergreen->SPI_INTERP_CONTROL_0.u32All, FLAT_SHADE_ENA_bit);
+ break;
+ case GL_SMOOTH:
+ CLEARbit(evergreen->SPI_INTERP_CONTROL_0.u32All, FLAT_SHADE_ENA_bit);
+ break;
+ default:
+ return;
+ }
+}
+
+static void evergreenLogicOpcode(GLcontext *ctx, GLenum logicop) //diff
+{
+ if (RGBA_LOGICOP_ENABLED(ctx))
+ evergreenSetLogicOpState(ctx);
+}
+
+static void evergreenPointSize(GLcontext * ctx, GLfloat size) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ /* We need to clamp to user defined range here, because
+ * the HW clamping happens only for per vertex point size. */
+ size = CLAMP(size, ctx->Point.MinSize, ctx->Point.MaxSize);
+
+ /* same size limits for AA, non-AA points */
+ size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
+
+ /* format is 12.4 fixed point */
+ SETfield(evergreen->PA_SU_POINT_SIZE.u32All, (int)(size * 8.0),
+ PA_SU_POINT_SIZE__HEIGHT_shift, PA_SU_POINT_SIZE__HEIGHT_mask);
+ SETfield(evergreen->PA_SU_POINT_SIZE.u32All, (int)(size * 8.0),
+ PA_SU_POINT_SIZE__WIDTH_shift, PA_SU_POINT_SIZE__WIDTH_mask);
+
+}
+
+static void evergreenPointParameter(GLcontext * ctx, GLenum pname, const GLfloat * param) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ /* format is 12.4 fixed point */
+ switch (pname) {
+ case GL_POINT_SIZE_MIN:
+ SETfield(evergreen->PA_SU_POINT_MINMAX.u32All, (int)(ctx->Point.MinSize * 8.0),
+ MIN_SIZE_shift, MIN_SIZE_mask);
+ evergreenPointSize(ctx, ctx->Point.Size);
+ break;
+ case GL_POINT_SIZE_MAX:
+ SETfield(evergreen->PA_SU_POINT_MINMAX.u32All, (int)(ctx->Point.MaxSize * 8.0),
+ MAX_SIZE_shift, MAX_SIZE_mask);
+ evergreenPointSize(ctx, ctx->Point.Size);
+ break;
+ case GL_POINT_DISTANCE_ATTENUATION:
+ break;
+ case GL_POINT_FADE_THRESHOLD_SIZE:
+ break;
+ default:
+ break;
+ }
+}
+
+static int evergreen_translate_stencil_func(int func) //same
+{
+ switch (func) {
+ case GL_NEVER:
+ return REF_NEVER;
+ case GL_LESS:
+ return REF_LESS;
+ case GL_EQUAL:
+ return REF_EQUAL;
+ case GL_LEQUAL:
+ return REF_LEQUAL;
+ case GL_GREATER:
+ return REF_GREATER;
+ case GL_NOTEQUAL:
+ return REF_NOTEQUAL;
+ case GL_GEQUAL:
+ return REF_GEQUAL;
+ case GL_ALWAYS:
+ return REF_ALWAYS;
+ }
+ return 0;
+}
+
+static void evergreenStencilFuncSeparate(GLcontext * ctx, GLenum face,
+ GLenum func, GLint ref, GLuint mask) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ const unsigned back = ctx->Stencil._BackFace;
+
+
+ EVERGREEN_STATECHANGE(context, db);
+
+ //front
+ SETfield(evergreen->DB_STENCILREFMASK.u32All, ctx->Stencil.Ref[0],
+ STENCILREF_shift, STENCILREF_mask);
+ SETfield(evergreen->DB_STENCILREFMASK.u32All, ctx->Stencil.ValueMask[0],
+ STENCILMASK_shift, STENCILMASK_mask);
+
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, evergreen_translate_stencil_func(ctx->Stencil.Function[0]),
+ STENCILFUNC_shift, STENCILFUNC_mask);
+
+ //back
+ SETfield(evergreen->DB_STENCILREFMASK_BF.u32All, ctx->Stencil.Ref[back],
+ STENCILREF_BF_shift, STENCILREF_BF_mask);
+ SETfield(evergreen->DB_STENCILREFMASK_BF.u32All, ctx->Stencil.ValueMask[back],
+ STENCILMASK_BF_shift, STENCILMASK_BF_mask);
+
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, evergreen_translate_stencil_func(ctx->Stencil.Function[back]),
+ STENCILFUNC_BF_shift, STENCILFUNC_BF_mask);
+}
+
+static void evergreenStencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ const unsigned back = ctx->Stencil._BackFace;
+
+ EVERGREEN_STATECHANGE(context, db);
+
+ // front
+ SETfield(evergreen->DB_STENCILREFMASK.u32All, ctx->Stencil.WriteMask[0],
+ STENCILWRITEMASK_shift, STENCILWRITEMASK_mask);
+
+ // back
+ SETfield(evergreen->DB_STENCILREFMASK_BF.u32All, ctx->Stencil.WriteMask[back],
+ STENCILWRITEMASK_BF_shift, STENCILWRITEMASK_BF_mask);
+
+}
+
+static int evergreen_translate_stencil_op(int op) //same
+{
+ switch (op) {
+ case GL_KEEP:
+ return STENCIL_KEEP;
+ case GL_ZERO:
+ return STENCIL_ZERO;
+ case GL_REPLACE:
+ return STENCIL_REPLACE;
+ case GL_INCR:
+ return STENCIL_INCR_CLAMP;
+ case GL_DECR:
+ return STENCIL_DECR_CLAMP;
+ case GL_INCR_WRAP_EXT:
+ return STENCIL_INCR_WRAP;
+ case GL_DECR_WRAP_EXT:
+ return STENCIL_DECR_WRAP;
+ case GL_INVERT:
+ return STENCIL_INVERT;
+ default:
+ WARN_ONCE("Do not know how to translate stencil op");
+ return STENCIL_KEEP;
+ }
+ return 0;
+}
+
+static void evergreenStencilOpSeparate(GLcontext * ctx, GLenum face,
+ GLenum fail, GLenum zfail, GLenum zpass) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ const unsigned back = ctx->Stencil._BackFace;
+
+ EVERGREEN_STATECHANGE(context, db);
+
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, evergreen_translate_stencil_op(ctx->Stencil.FailFunc[0]),
+ STENCILFAIL_shift, STENCILFAIL_mask);
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, evergreen_translate_stencil_op(ctx->Stencil.ZFailFunc[0]),
+ STENCILZFAIL_shift, STENCILZFAIL_mask);
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, evergreen_translate_stencil_op(ctx->Stencil.ZPassFunc[0]),
+ STENCILZPASS_shift, STENCILZPASS_mask);
+
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, evergreen_translate_stencil_op(ctx->Stencil.FailFunc[back]),
+ STENCILFAIL_BF_shift, STENCILFAIL_BF_mask);
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, evergreen_translate_stencil_op(ctx->Stencil.ZFailFunc[back]),
+ STENCILZFAIL_BF_shift, STENCILZFAIL_BF_mask);
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, evergreen_translate_stencil_op(ctx->Stencil.ZPassFunc[back]),
+ STENCILZPASS_BF_shift, STENCILZPASS_BF_mask);
+}
+
+static void evergreenViewport(GLcontext * ctx,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) //diff in evergreenUpdateWindow
+{
+ evergreenUpdateWindow(ctx, 0);
+
+ radeon_viewport(ctx, x, y, width, height);
+}
+
+static void evergreenDepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) //diff in evergreenUpdateWindow
+{
+ evergreenUpdateWindow(ctx, 0);
+}
+
+static void evergreenLineWidth(GLcontext * ctx, GLfloat widthf) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ uint32_t lineWidth = (uint32_t)((widthf * 0.5) * (1 << 4));
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ if (lineWidth > 0xFFFF)
+ lineWidth = 0xFFFF;
+ SETfield(evergreen->PA_SU_LINE_CNTL.u32All,(uint16_t)lineWidth,
+ PA_SU_LINE_CNTL__WIDTH_shift, PA_SU_LINE_CNTL__WIDTH_mask);
+}
+
+static void evergreenLineStipple(GLcontext *ctx, GLint factor, GLushort pattern) //same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ SETfield(evergreen->PA_SC_LINE_STIPPLE.u32All, pattern, LINE_PATTERN_shift, LINE_PATTERN_mask);
+ SETfield(evergreen->PA_SC_LINE_STIPPLE.u32All, (factor-1), REPEAT_COUNT_shift, REPEAT_COUNT_mask);
+ SETfield(evergreen->PA_SC_LINE_STIPPLE.u32All, 1, AUTO_RESET_CNTL_shift, AUTO_RESET_CNTL_mask);
+}
+
+static void evergreenPolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units) //diff :
+ //all register here offset diff, bits same
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ GLfloat constant = units;
+ GLchar depth = 0;
+
+ EVERGREEN_STATECHANGE(context, pa);
+
+ switch (ctx->Visual.depthBits) {
+ case 16:
+ constant *= 4.0;
+ depth = -16;
+ break;
+ case 24:
+ constant *= 2.0;
+ depth = -24;
+ break;
+ }
+
+ factor *= 12.0;
+ SETfield(evergreen->PA_SU_POLY_OFFSET_DB_FMT_CNTL.u32All, depth,
+ POLY_OFFSET_NEG_NUM_DB_BITS_shift, POLY_OFFSET_NEG_NUM_DB_BITS_mask);
+ //evergreen->PA_SU_POLY_OFFSET_CLAMP.f32All = constant; //???
+ evergreen->PA_SU_POLY_OFFSET_FRONT_SCALE.f32All = factor;
+ evergreen->PA_SU_POLY_OFFSET_FRONT_OFFSET.f32All = constant;
+ evergreen->PA_SU_POLY_OFFSET_BACK_SCALE.f32All = factor;
+ evergreen->PA_SU_POLY_OFFSET_BACK_OFFSET.f32All = constant;
+}
+
+static void evergreenPolygonMode(GLcontext * ctx, GLenum face, GLenum mode) //same
+{
+ (void)face;
+ (void)mode;
+
+ evergreenUpdatePolygonMode(ctx);
+}
+
+static void evergreenRenderMode(GLcontext * ctx, GLenum mode) //same
+{
+}
+
+//TODO : move to kernel.
+static void evergreenInitSQConfig(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ uint32_t uSqNumCfInsts, uMaxGPRs, uMaxThreads, uMaxStackEntries, uPSThreadCount, uOtherThreadCount;
+ uint32_t NUM_PS_GPRS, NUM_VS_GPRS, NUM_GS_GPRS, NUM_ES_GPRS, NUM_HS_GPRS, NUM_LS_GPRS, NUM_CLAUSE_TEMP_GPRS;
+ GLboolean bVC_ENABLE = GL_TRUE;
+
+ R600_STATECHANGE(context, sq);
+
+ switch (context->radeon.radeonScreen->chip_family)
+ {
+ case CHIP_FAMILY_CEDAR:
+ uSqNumCfInsts = 1;
+ bVC_ENABLE = GL_FALSE;
+ uMaxGPRs = 256;
+ uPSThreadCount = 96;
+ uMaxThreads = 192;
+ uMaxStackEntries = 256;
+ break;
+ case CHIP_FAMILY_REDWOOD:
+ uSqNumCfInsts = 2;
+ bVC_ENABLE = GL_TRUE;
+ uMaxGPRs = 256;
+ uPSThreadCount = 128;
+ uMaxThreads = 248;
+ uMaxStackEntries = 256;
+ break;
+ case CHIP_FAMILY_JUNIPER:
+ uSqNumCfInsts = 2;
+ bVC_ENABLE = GL_TRUE;
+ uMaxGPRs = 256;
+ uPSThreadCount = 128;
+ uMaxThreads = 248;
+ uMaxStackEntries = 512;
+ break;
+ case CHIP_FAMILY_CYPRESS:
+ uSqNumCfInsts = 2;
+ bVC_ENABLE = GL_TRUE;
+ uMaxGPRs = 256;
+ uPSThreadCount = 128;
+ uMaxThreads = 248;
+ uMaxStackEntries = 512;
+ break;
+ case CHIP_FAMILY_HEMLOCK:
+ uSqNumCfInsts = 2;//?
+ bVC_ENABLE = GL_TRUE;
+ uMaxGPRs = 256;
+ uPSThreadCount = 128;
+ uMaxThreads = 248;
+ uMaxStackEntries = 512;
+ break;
+ default:
+ uSqNumCfInsts = 2;
+ bVC_ENABLE = GL_TRUE;
+ uMaxGPRs = 256;
+ uPSThreadCount = 128;
+ uMaxThreads = 248;
+ uMaxStackEntries = 512;
+ break;
+ }
+
+ evergreen->evergreen_config.SQ_DYN_GPR_CNTL_PS_FLUSH_REQ.u32All = 0;
+
+ evergreen->evergreen_config.SPI_CONFIG_CNTL.u32All = 0;
+ evergreen->evergreen_config.SPI_CONFIG_CNTL_1.u32All = 0;
+ SETfield(evergreen->evergreen_config.SPI_CONFIG_CNTL_1.u32All, 4,
+ EG_SPI_CONFIG_CNTL_1__VTX_DONE_DELAY_shift,
+ EG_SPI_CONFIG_CNTL_1__VTX_DONE_DELAY_mask);
+
+ evergreen->evergreen_config.CP_PERFMON_CNTL.u32All = 0;
+
+ evergreen->evergreen_config.SQ_MS_FIFO_SIZES.u32All = 0;
+ SETfield(evergreen->evergreen_config.SQ_MS_FIFO_SIZES.u32All, 16 * uSqNumCfInsts,
+ EG_SQ_MS_FIFO_SIZES__CACHE_FIFO_SIZE_shift,
+ EG_SQ_MS_FIFO_SIZES__CACHE_FIFO_SIZE_mask);
+ SETfield(evergreen->evergreen_config.SQ_MS_FIFO_SIZES.u32All, 0x4,
+ EG_SQ_MS_FIFO_SIZES__FETCH_FIFO_HIWATER_shift,
+ EG_SQ_MS_FIFO_SIZES__FETCH_FIFO_HIWATER_mask);
+ SETfield(evergreen->evergreen_config.SQ_MS_FIFO_SIZES.u32All, 0xE0,
+ EG_SQ_MS_FIFO_SIZES__DONE_FIFO_HIWATER_shift,
+ EG_SQ_MS_FIFO_SIZES__DONE_FIFO_HIWATER_mask);
+ SETfield(evergreen->evergreen_config.SQ_MS_FIFO_SIZES.u32All, 0x8,
+ EG_SQ_MS_FIFO_SIZES__ALU_UPDATE_FIFO_HIWATER_shift,
+ EG_SQ_MS_FIFO_SIZES__ALU_UPDATE_FIFO_HIWATER_mask);
+
+ if(bVC_ENABLE == GL_TRUE)
+ {
+ SETbit(evergreen->evergreen_config.SQ_CONFIG.u32All,
+ EG_SQ_CONFIG__VC_ENABLE_bit);
+ }
+ else
+ {
+ CLEARbit(evergreen->evergreen_config.SQ_CONFIG.u32All,
+ EG_SQ_CONFIG__VC_ENABLE_bit);
+ }
+ SETbit(evergreen->evergreen_config.SQ_CONFIG.u32All,
+ EG_SQ_CONFIG__EXPORT_SRC_C_bit);
+ SETfield(evergreen->evergreen_config.SQ_CONFIG.u32All, 0,
+ EG_SQ_CONFIG__PS_PRIO_shift,
+ EG_SQ_CONFIG__PS_PRIO_mask);
+ SETfield(evergreen->evergreen_config.SQ_CONFIG.u32All, 1,
+ EG_SQ_CONFIG__VS_PRIO_shift,
+ EG_SQ_CONFIG__VS_PRIO_mask);
+ SETfield(evergreen->evergreen_config.SQ_CONFIG.u32All, 2,
+ EG_SQ_CONFIG__GS_PRIO_shift,
+ EG_SQ_CONFIG__GS_PRIO_mask);
+ SETfield(evergreen->evergreen_config.SQ_CONFIG.u32All, 3,
+ EG_SQ_CONFIG__ES_PRIO_shift,
+ EG_SQ_CONFIG__ES_PRIO_mask);
+
+ NUM_CLAUSE_TEMP_GPRS = 4;
+ NUM_PS_GPRS = ((uMaxGPRs-(4*2))*12/32); // 93
+ NUM_VS_GPRS = ((uMaxGPRs-(4*2))*6/32); // 46
+ NUM_GS_GPRS = ((uMaxGPRs-(4*2))*4/32); // 31
+ NUM_ES_GPRS = ((uMaxGPRs-(4*2))*4/32); // 31
+ NUM_HS_GPRS = ((uMaxGPRs-(4*2))*3/32); // 23
+ NUM_LS_GPRS = ((uMaxGPRs-(4*2))*3/32); // 23
+
+ evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_1.u32All = 0;
+ evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_2.u32All = 0;
+ evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_3.u32All = 0;
+
+ SETfield(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_1.u32All, NUM_PS_GPRS,
+ NUM_PS_GPRS_shift, NUM_PS_GPRS_mask);
+ SETfield(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_1.u32All, NUM_VS_GPRS,
+ NUM_VS_GPRS_shift, NUM_VS_GPRS_mask);
+ SETfield(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_1.u32All, NUM_CLAUSE_TEMP_GPRS,
+ NUM_CLAUSE_TEMP_GPRS_shift, NUM_CLAUSE_TEMP_GPRS_mask);
+ SETfield(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_2.u32All, NUM_GS_GPRS,
+ NUM_GS_GPRS_shift, NUM_GS_GPRS_mask);
+ SETfield(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_2.u32All, NUM_ES_GPRS,
+ NUM_ES_GPRS_shift, NUM_ES_GPRS_mask);
+ SETfield(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_3.u32All, NUM_HS_GPRS,
+ NUM_PS_GPRS_shift, NUM_PS_GPRS_mask);
+ SETfield(evergreen->evergreen_config.SQ_GPR_RESOURCE_MGMT_3.u32All, NUM_LS_GPRS,
+ NUM_VS_GPRS_shift, NUM_VS_GPRS_mask);
+
+ uOtherThreadCount = (((uMaxThreads-uPSThreadCount)/6)/8)*8;
+ evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT.u32All = 0;
+ evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT_2.u32All = 0;
+ SETfield(evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT.u32All, uPSThreadCount,
+ NUM_PS_THREADS_shift, NUM_PS_THREADS_mask);
+ SETfield(evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT.u32All, uOtherThreadCount,
+ NUM_VS_THREADS_shift, NUM_VS_THREADS_mask);
+ SETfield(evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT.u32All, uOtherThreadCount,
+ NUM_GS_THREADS_shift, NUM_GS_THREADS_mask);
+ SETfield(evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT.u32All, uOtherThreadCount,
+ NUM_ES_THREADS_shift, NUM_ES_THREADS_mask);
+ SETfield(evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT_2.u32All, uOtherThreadCount,
+ NUM_PS_THREADS_shift, NUM_PS_THREADS_mask);
+ SETfield(evergreen->evergreen_config.SQ_THREAD_RESOURCE_MGMT_2.u32All, uOtherThreadCount,
+ NUM_VS_THREADS_shift, NUM_VS_THREADS_mask);
+
+ uMaxStackEntries = ((uMaxStackEntries*1)/6);
+ evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_1.u32All = 0;
+ evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_2.u32All = 0;
+ evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_3.u32All = 0;
+ SETfield(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_1.u32All, uMaxStackEntries,
+ NUM_PS_STACK_ENTRIES_shift, NUM_PS_STACK_ENTRIES_mask);
+ SETfield(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_1.u32All, uMaxStackEntries,
+ NUM_VS_STACK_ENTRIES_shift, NUM_VS_STACK_ENTRIES_mask);
+ SETfield(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_2.u32All, uMaxStackEntries,
+ NUM_GS_STACK_ENTRIES_shift, NUM_GS_STACK_ENTRIES_mask);
+ SETfield(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_2.u32All, uMaxStackEntries,
+ NUM_ES_STACK_ENTRIES_shift, NUM_ES_STACK_ENTRIES_mask);
+ SETfield(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_3.u32All, uMaxStackEntries,
+ NUM_PS_STACK_ENTRIES_shift, NUM_PS_STACK_ENTRIES_mask);
+ SETfield(evergreen->evergreen_config.SQ_STACK_RESOURCE_MGMT_3.u32All, uMaxStackEntries,
+ NUM_VS_STACK_ENTRIES_shift, NUM_VS_STACK_ENTRIES_mask);
+
+ evergreen->evergreen_config.PA_SC_FORCE_EOV_MAX_CNTS.u32All = 0;
+ SETfield(evergreen->evergreen_config.PA_SC_FORCE_EOV_MAX_CNTS.u32All, 4095,
+ EG_PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_CLK_CNT_shift,
+ EG_PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_CLK_CNT_mask);
+ SETfield(evergreen->evergreen_config.PA_SC_FORCE_EOV_MAX_CNTS.u32All, 255,
+ EG_PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_REZ_CNT_shift,
+ EG_PA_SC_FORCE_EOV_MAX_CNTS__FORCE_EOV_MAX_REZ_CNT_mask);
+
+ evergreen->evergreen_config.VGT_CACHE_INVALIDATION.u32All = 0;
+ SETfield(evergreen->evergreen_config.VGT_CACHE_INVALIDATION.u32All, 2,
+ EG_VGT_CACHE_INVALIDATION__CACHE_INVALIDATION_shift,
+ EG_VGT_CACHE_INVALIDATION__CACHE_INVALIDATION_mask);
+
+ evergreen->evergreen_config.VGT_GS_VERTEX_REUSE.u32All = 0;
+ SETfield(evergreen->evergreen_config.VGT_GS_VERTEX_REUSE.u32All, 16,
+ VERT_REUSE_shift,
+ VERT_REUSE_mask);
+
+ evergreen->evergreen_config.PA_SC_LINE_STIPPLE_STATE.u32All = 0;
+
+ evergreen->evergreen_config.PA_CL_ENHANCE.u32All = 0;
+ SETbit(evergreen->evergreen_config.PA_CL_ENHANCE.u32All,
+ CLIP_VTX_REORDER_ENA_bit);
+ SETfield(evergreen->evergreen_config.PA_CL_ENHANCE.u32All, 3,
+ NUM_CLIP_SEQ_shift,
+ NUM_CLIP_SEQ_mask);
+}
+
+void evergreenInitState(GLcontext * ctx) //diff
+{
+ context_t *context = R700_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+
+ int id = 0;
+
+ //calloc should have done this
+ memset(evergreen, 0, sizeof(EVERGREEN_CHIP_CONTEXT));
+
+ // Disable window clipping and offset:
+ SETfield(evergreen->PA_SC_WINDOW_OFFSET.u32All, 0,
+ EG_PA_SC_WINDOW_OFFSET__WINDOW_X_OFFSET_shift, EG_PA_SC_WINDOW_OFFSET__WINDOW_X_OFFSET_mask);
+ SETfield(evergreen->PA_SC_WINDOW_OFFSET.u32All, 0,
+ EG_PA_SC_WINDOW_OFFSET__WINDOW_Y_OFFSET_shift, EG_PA_SC_WINDOW_OFFSET__WINDOW_Y_OFFSET_mask);
+
+ SETbit(evergreen->PA_SC_WINDOW_SCISSOR_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
+
+ evergreen->PA_SC_CLIPRECT_RULE.u32All = 0x0000FFFF;
+
+ evergreen->PA_SC_EDGERULE.u32All = 0xAAAAAAAA;
+
+ // Set up Z min/max:
+ evergreen->viewport[id].PA_SC_VPORT_ZMIN_0.f32All = 0.0;
+ evergreen->viewport[id].PA_SC_VPORT_ZMAX_0.f32All = 1.0;
+
+ SETfield(evergreen->CB_TARGET_MASK.u32All, 0xF, TARGET0_ENABLE_shift, TARGET0_ENABLE_mask);
+ SETfield(evergreen->CB_SHADER_MASK.u32All, 0xF, OUTPUT0_ENABLE_shift, OUTPUT0_ENABLE_mask);
+
+ SETfield(evergreen->SPI_BARYC_CNTL.u32All, 1,
+ EG_SPI_BARYC_CNTL__PERSP_CENTROID_ENA_shift,
+ EG_SPI_BARYC_CNTL__PERSP_CENTROID_ENA_mask);
+ SETfield(evergreen->SPI_BARYC_CNTL.u32All, 1,
+ EG_SPI_BARYC_CNTL__LINEAR_CENTROID_ENA_shift,
+ EG_SPI_BARYC_CNTL__LINEAR_CENTROID_ENA_mask);
+
+ // Turn off vgt reuse:
+ evergreen->VGT_REUSE_OFF.u32All = 0;
+ SETbit(evergreen->VGT_REUSE_OFF.u32All, REUSE_OFF_bit);
+
+ // Specify offsetting and clamp values for vertices:
+ evergreen->VGT_MAX_VTX_INDX.u32All = 0xFFFFFF;
+ evergreen->VGT_MIN_VTX_INDX.u32All = 0;
+ evergreen->VGT_INDX_OFFSET.u32All = 0;
+
+ evergreen->VGT_DMA_NUM_INSTANCES.u32All = 1;
+
+ // Do not alpha blend:
+ SETfield(evergreen->SX_ALPHA_TEST_CONTROL.u32All, REF_NEVER,
+ ALPHA_FUNC_shift, ALPHA_FUNC_mask);
+ CLEARbit(evergreen->SX_ALPHA_TEST_CONTROL.u32All, ALPHA_TEST_ENABLE_bit);
+
+ evergreen->SPI_VS_OUT_ID_0.u32All = 0x03020100;
+ evergreen->SPI_VS_OUT_ID_1.u32All = 0x07060504;
+
+ evergreen->SPI_PS_INPUT_CNTL[0].u32All = 0x00000800;
+ evergreen->SPI_PS_INPUT_CNTL[1].u32All = 0x00000801;
+ evergreen->SPI_PS_INPUT_CNTL[2].u32All = 0x00000802;
+
+
+ // Depth buffer currently disabled:
+ evergreen->DB_DEPTH_CONTROL.u32All = 0;
+ SETbit(evergreen->DB_DEPTH_CONTROL.u32All, Z_WRITE_ENABLE_bit);
+ SETfield(evergreen->DB_DEPTH_CONTROL.u32All, FRAG_ALWAYS,
+ ZFUNC_shift, ZFUNC_mask);
+
+ evergreen->DB_Z_READ_BASE.u32All = 0;
+ evergreen->DB_Z_WRITE_BASE.u32All = 0;
+
+ evergreen->DB_DEPTH_CLEAR.f32All = 1.0;
+
+ evergreen->DB_DEPTH_VIEW.u32All = 0;
+
+ evergreen->DB_SHADER_CONTROL.u32All = 0;
+ SETbit(evergreen->DB_SHADER_CONTROL.u32All, EG_DB_SHADER_CONTROL__DUAL_EXPORT_ENABLE_bit);
+
+ evergreen->DB_Z_INFO.u32All = 0;
+ SETfield(evergreen->DB_Z_INFO.u32All , ARRAY_1D_TILED_THIN1,
+ EG_DB_Z_INFO__ARRAY_MODE_shift, EG_DB_Z_INFO__ARRAY_MODE_mask);
+ SETfield(evergreen->DB_Z_INFO.u32All , EG_Z_24,
+ EG_DB_Z_INFO__FORMAT_shift, EG_DB_Z_INFO__FORMAT_mask);
+ SETfield(evergreen->DB_Z_INFO.u32All , EG_ADDR_SURF_TILE_SPLIT_256B,
+ EG_DB_Z_INFO__TILE_SPLIT_shift, EG_DB_Z_INFO__TILE_SPLIT_mask);
+ SETfield(evergreen->DB_Z_INFO.u32All , EG_ADDR_SURF_8_BANK,
+ EG_DB_Z_INFO__NUM_BANKS_shift, EG_DB_Z_INFO__NUM_BANKS_mask);
+ SETfield(evergreen->DB_Z_INFO.u32All , EG_ADDR_SURF_BANK_WIDTH_1,
+ EG_DB_Z_INFO__BANK_WIDTH_shift, EG_DB_Z_INFO__BANK_WIDTH_mask);
+ SETfield(evergreen->DB_Z_INFO.u32All , EG_ADDR_SURF_BANK_HEIGHT_1,
+ EG_DB_Z_INFO__BANK_HEIGHT_shift, EG_DB_Z_INFO__BANK_HEIGHT_mask);
+
+ evergreen->DB_STENCIL_INFO.u32All = 0;
+ CLEARbit(evergreen->DB_STENCIL_INFO.u32All, EG_DB_STENCIL_INFO__FORMAT_bit);
+ SETfield(evergreen->DB_STENCIL_INFO.u32All, EG_ADDR_SURF_TILE_SPLIT_256B,
+ EG_DB_STENCIL_INFO__TILE_SPLIT_shift, EG_DB_STENCIL_INFO__TILE_SPLIT_mask);
+
+ evergreen->DB_RENDER_CONTROL.u32All = 0;
+
+ evergreen->DB_RENDER_OVERRIDE.u32All = 0;
+ SETfield(evergreen->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
+ SETfield(evergreen->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
+ SETfield(evergreen->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
+
+ // Disable ROP3 modes by setting src to dst copy:
+ SETfield(evergreen->CB_COLOR_CONTROL.u32All, 0xCC,
+ EG_CB_COLOR_CONTROL__ROP3_shift,
+ EG_CB_COLOR_CONTROL__ROP3_mask);
+ SETfield(evergreen->CB_COLOR_CONTROL.u32All, EG_CB_NORMAL,
+ EG_CB_COLOR_CONTROL__MODE_shift,
+ EG_CB_COLOR_CONTROL__MODE_mask);
+
+ SETfield(evergreen->CB_BLEND0_CONTROL.u32All,
+ BLEND_ONE, COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
+
+ SETfield(evergreen->CB_BLEND0_CONTROL.u32All,
+ BLEND_ONE, ALPHA_SRCBLEND_shift, ALPHA_SRCBLEND_mask);
+
+ //evergreen->PA_CL_CLIP_CNTL.CLIP_DISABLE = 1;
+
+ SETbit(evergreen->PA_CL_CLIP_CNTL.u32All, DX_LINEAR_ATTR_CLIP_ENA_bit);
+
+ // Set up the culling control register:
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, 2,
+ POLYMODE_FRONT_PTYPE_shift, POLYMODE_FRONT_PTYPE_mask); // draw using triangles
+ SETfield(evergreen->PA_SU_SC_MODE_CNTL.u32All, 2,
+ POLYMODE_BACK_PTYPE_shift, POLYMODE_BACK_PTYPE_mask); // draw using triangles
+
+ // Do scale XY or X by 1/W0. eg:
+ evergreen->bEnablePerspective = GL_TRUE;
+
+ CLEARbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_XY_FMT_bit);
+ CLEARbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_Z_FMT_bit);
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VTX_W0_FMT_bit);
+
+ // Enable viewport scaling for all three axis:
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VPORT_X_SCALE_ENA_bit);
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VPORT_X_OFFSET_ENA_bit);
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VPORT_Y_SCALE_ENA_bit);
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VPORT_Y_OFFSET_ENA_bit);
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VPORT_Z_SCALE_ENA_bit);
+ SETbit(evergreen->PA_CL_VTE_CNTL.u32All, VPORT_Z_OFFSET_ENA_bit);
+
+ // Set up point sizes and min/max values:
+ SETfield(evergreen->PA_SU_POINT_SIZE.u32All, 0x8,
+ PA_SU_POINT_SIZE__HEIGHT_shift, PA_SU_POINT_SIZE__HEIGHT_mask);
+ SETfield(evergreen->PA_SU_POINT_SIZE.u32All, 0x8,
+ PA_SU_POINT_SIZE__WIDTH_shift, PA_SU_POINT_SIZE__WIDTH_mask);
+ CLEARfield(evergreen->PA_SU_POINT_MINMAX.u32All, MIN_SIZE_mask);
+ SETfield(evergreen->PA_SU_POINT_MINMAX.u32All, 0x8000, MAX_SIZE_shift, MAX_SIZE_mask);
+ SETfield(evergreen->PA_SU_LINE_CNTL.u32All,0x8,
+ PA_SU_LINE_CNTL__WIDTH_shift, PA_SU_LINE_CNTL__WIDTH_mask);
+
+ // Set up line control:
+ evergreen->PA_SC_LINE_CNTL.u32All = 0;
+ CLEARbit(evergreen->PA_SC_LINE_CNTL.u32All, EXPAND_LINE_WIDTH_bit);
+ SETbit(evergreen->PA_SC_LINE_CNTL.u32All, LAST_PIXEL_bit);
+
+ // Set up vertex control:
+ evergreen->PA_SU_VTX_CNTL.u32All = 0;
+ CLEARfield(evergreen->PA_SU_VTX_CNTL.u32All, QUANT_MODE_mask);
+ SETbit(evergreen->PA_SU_VTX_CNTL.u32All, PIX_CENTER_bit);
+ SETfield(evergreen->PA_SU_VTX_CNTL.u32All, X_ROUND_TO_EVEN,
+ PA_SU_VTX_CNTL__ROUND_MODE_shift, PA_SU_VTX_CNTL__ROUND_MODE_mask);
+
+ // to 1.0 = no guard band:
+ evergreen->PA_CL_GB_VERT_CLIP_ADJ.u32All = 0x3F800000; // 1.0
+ evergreen->PA_CL_GB_VERT_DISC_ADJ.u32All = 0x3F800000; // 1.0
+ evergreen->PA_CL_GB_HORZ_CLIP_ADJ.u32All = 0x3F800000; // 1.0
+ evergreen->PA_CL_GB_HORZ_DISC_ADJ.u32All = 0x3F800000; // 1.0
+
+ // Diable color compares:
+ SETfield(evergreen->CB_CLRCMP_CONTROL.u32All, CLRCMP_DRAW_ALWAYS,
+ CLRCMP_FCN_SRC_shift, CLRCMP_FCN_SRC_mask);
+ SETfield(evergreen->CB_CLRCMP_CONTROL.u32All, CLRCMP_DRAW_ALWAYS,
+ CLRCMP_FCN_DST_shift, CLRCMP_FCN_DST_mask);
+ SETfield(evergreen->CB_CLRCMP_CONTROL.u32All, CLRCMP_SEL_SRC,
+ CLRCMP_FCN_SEL_shift, CLRCMP_FCN_SEL_mask);
+
+ // Zero out source:
+ evergreen->CB_CLRCMP_SRC.u32All = 0x00000000;
+
+ // Put a compare color in for error checking:
+ evergreen->CB_CLRCMP_DST.u32All = 0x000000FF;
+
+ // Set up color compare mask:
+ evergreen->CB_CLRCMP_MSK.u32All = 0xFFFFFFFF;
+
+ // Enable all samples for multi-sample anti-aliasing:
+ evergreen->PA_SC_AA_MASK.u32All = 0xFFFFFFFF;
+ // Turn off AA:
+ evergreen->PA_SC_AA_CONFIG.u32All = 0;
+
+ SETfield(evergreen->VGT_OUT_DEALLOC_CNTL.u32All, 16,
+ DEALLOC_DIST_shift, DEALLOC_DIST_mask);
+ SETfield(evergreen->VGT_VERTEX_REUSE_BLOCK_CNTL.u32All, 14,
+ VTX_REUSE_DEPTH_shift, VTX_REUSE_DEPTH_mask);
+
+ evergreen->SX_MISC.u32All = 0;
+
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All, 1,
+ EG_CB_COLOR0_INFO__SOURCE_FORMAT_shift, EG_CB_COLOR0_INFO__SOURCE_FORMAT_mask);
+ SETbit(evergreen->render_target[id].CB_COLOR0_INFO.u32All, EG_CB_COLOR0_INFO__BLEND_CLAMP_bit);
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All, 0,
+ EG_CB_COLOR0_INFO__NUMBER_TYPE_shift, EG_CB_COLOR0_INFO__NUMBER_TYPE_mask);
+
+ SETfield(evergreen->render_target[id].CB_COLOR0_INFO.u32All, SWAP_STD,
+ EG_CB_COLOR0_INFO__COMP_SWAP_shift, EG_CB_COLOR0_INFO__COMP_SWAP_mask);
+
+ evergreen->render_target[id].CB_COLOR0_VIEW.u32All = 0;
+ evergreen->render_target[id].CB_COLOR0_CMASK.u32All = 0;
+ evergreen->render_target[id].CB_COLOR0_FMASK.u32All = 0;
+ evergreen->render_target[id].CB_COLOR0_FMASK_SLICE.u32All = 0;
+
+ evergreenInitSQConfig(ctx);
+
+ context->radeon.hw.all_dirty = GL_TRUE;
+}
+
+void evergreenInitStateFuncs(radeonContextPtr radeon, struct dd_function_table *functions)
+{
+ functions->UpdateState = evergreenInvalidateState;
+ functions->AlphaFunc = evergreenAlphaFunc;
+ functions->BlendColor = evergreenBlendColor;
+ functions->BlendEquationSeparate = evergreenBlendEquationSeparate;
+ functions->BlendFuncSeparate = evergreenBlendFuncSeparate;
+ functions->Enable = evergreenEnable;
+ functions->ColorMask = evergreenColorMask;
+ functions->DepthFunc = evergreenDepthFunc;
+ functions->DepthMask = evergreenDepthMask;
+ functions->CullFace = evergreenCullFace;
+ functions->Fogfv = evergreenFogfv;
+ functions->FrontFace = evergreenFrontFace;
+ functions->ShadeModel = evergreenShadeModel;
+ functions->LogicOpcode = evergreenLogicOpcode;
+
+ /* ARB_point_parameters */
+ functions->PointParameterfv = evergreenPointParameter;
+
+ /* Stencil related */
+ functions->StencilFuncSeparate = evergreenStencilFuncSeparate;
+ functions->StencilMaskSeparate = evergreenStencilMaskSeparate;
+ functions->StencilOpSeparate = evergreenStencilOpSeparate;
+
+ /* Viewport related */
+ functions->Viewport = evergreenViewport;
+ functions->DepthRange = evergreenDepthRange;
+ functions->PointSize = evergreenPointSize;
+ functions->LineWidth = evergreenLineWidth;
+ functions->LineStipple = evergreenLineStipple;
+
+ functions->PolygonOffset = evergreenPolygonOffset;
+ functions->PolygonMode = evergreenPolygonMode;
+
+ functions->RenderMode = evergreenRenderMode;
+
+ functions->ClipPlane = evergreenClipPlane;
+
+ functions->Scissor = radeonScissor;
+
+ functions->DrawBuffer = radeonDrawBuffer;
+ functions->ReadBuffer = radeonReadBuffer;
+
+ if (radeon->radeonScreen->kernel_mm) {
+ functions->CopyPixels = _mesa_meta_CopyPixels;
+ functions->DrawPixels = _mesa_meta_DrawPixels;
+ functions->ReadPixels = radeonReadPixels;
+ }
+}
+
+
diff --git a/src/mesa/drivers/dri/r600/evergreen_state.h b/src/mesa/drivers/dri/r600/evergreen_state.h
new file mode 100644
index 00000000000..ffdb56b38ae
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_state.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#ifndef _EVERGREEN_STATE_H_
+#define _EVERGREEN_STATE_H_
+
+#include "main/mtypes.h"
+
+#include "r600_context.h"
+
+extern void evergreenUpdateStateParameters(GLcontext * ctx, GLuint new_state);
+extern void evergreenUpdateShaders(GLcontext * ctx);
+extern void evergreenUpdateShaderStates(GLcontext * ctx);
+
+extern void evergreeUpdateShaders(GLcontext * ctx);
+
+extern void evergreenUpdateViewportOffset(GLcontext * ctx);
+
+extern void evergreenInitState(GLcontext * ctx);
+extern void evergreenInitStateFuncs (radeonContextPtr radeon, struct dd_function_table *functions);
+
+extern void evergreenSetScissor(context_t *context);
+
+#endif /* _EVERGREEN_STATE_H_ */
diff --git a/src/mesa/drivers/dri/r600/evergreen_tex.c b/src/mesa/drivers/dri/r600/evergreen_tex.c
new file mode 100644
index 00000000000..8b42045ebb6
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_tex.c
@@ -0,0 +1,1551 @@
+/*
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/colormac.h"
+#include "main/context.h"
+#include "main/enums.h"
+#include "main/image.h"
+#include "main/teximage.h"
+#include "main/mipmap.h"
+#include "main/simple_list.h"
+#include "main/texstore.h"
+#include "main/texobj.h"
+
+#include "texmem.h"
+
+#include "r600_context.h"
+#include "radeon_mipmap_tree.h"
+#include "evergreen_diff.h"
+#include "evergreen_tex.h"
+#include "evergreen_fragprog.h"
+#include "evergreen_vertprog.h"
+
+#include "r600_tex.h"
+
+static unsigned int evergreen_translate_wrap_mode(GLenum wrapmode)
+{
+ switch(wrapmode) {
+ case GL_REPEAT: return SQ_TEX_WRAP;
+ case GL_CLAMP: return SQ_TEX_CLAMP_HALF_BORDER;
+ case GL_CLAMP_TO_EDGE: return SQ_TEX_CLAMP_LAST_TEXEL;
+ case GL_CLAMP_TO_BORDER: return SQ_TEX_CLAMP_BORDER;
+ case GL_MIRRORED_REPEAT: return SQ_TEX_MIRROR;
+ case GL_MIRROR_CLAMP_EXT: return SQ_TEX_MIRROR_ONCE_HALF_BORDER;
+ case GL_MIRROR_CLAMP_TO_EDGE_EXT: return SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
+ case GL_MIRROR_CLAMP_TO_BORDER_EXT: return SQ_TEX_MIRROR_ONCE_BORDER;
+ default:
+ radeon_error("bad wrap mode in %s", __FUNCTION__);
+ return 0;
+ }
+}
+
+static GLboolean evergreenGetTexFormat(struct gl_texture_object *tObj, gl_format mesa_format)
+{
+ radeonTexObj *t = radeon_tex_obj(tObj);
+
+ CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
+ FORMAT_COMP_X_shift,
+ FORMAT_COMP_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
+ FORMAT_COMP_Y_shift,
+ FORMAT_COMP_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
+ FORMAT_COMP_Z_shift,
+ FORMAT_COMP_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
+ FORMAT_COMP_W_shift,
+ FORMAT_COMP_W_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE1, ARRAY_LINEAR_GENERAL,
+ EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_mask);
+
+ switch (mesa_format) /* This is mesa format. */
+ {
+ case MESA_FORMAT_RGBA8888:
+ case MESA_FORMAT_SIGNED_RGBA8888:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ if (mesa_format == MESA_FORMAT_SIGNED_RGBA8888) {
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
+ FORMAT_COMP_X_shift, FORMAT_COMP_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
+ FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
+ FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
+ FORMAT_COMP_W_shift, FORMAT_COMP_W_mask);
+ }
+ break;
+ case MESA_FORMAT_RGBA8888_REV:
+ case MESA_FORMAT_SIGNED_RGBA8888_REV:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ if (mesa_format == MESA_FORMAT_SIGNED_RGBA8888_REV) {
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
+ FORMAT_COMP_X_shift, FORMAT_COMP_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
+ FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
+ FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_SIGNED,
+ FORMAT_COMP_W_shift, FORMAT_COMP_W_mask);
+ }
+ break;
+ case MESA_FORMAT_ARGB8888:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_XRGB8888:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_XRGB8888_REV:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_ARGB8888_REV:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_RGB888:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_RGB565:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_5_6_5,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_RGB565_REV:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_5_6_5,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_ARGB4444:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_4_4_4_4,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_ARGB4444_REV:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_4_4_4_4,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_ARGB1555:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_1_5_5_5,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_ARGB1555_REV:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_1_5_5_5,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_AL88:
+ case MESA_FORMAT_AL88_REV: /* TODO : Check this. */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_RGB332:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_3_3_2,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_A8: /* ZERO, ZERO, ZERO, X */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_L8: /* X, X, X, ONE */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_I8: /* X, X, X, X */
+ case MESA_FORMAT_CI8:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_RGB_DXT1: /* not supported yet */
+ case MESA_FORMAT_RGBA_DXT1: /* not supported yet */
+ case MESA_FORMAT_RGBA_DXT3: /* not supported yet */
+ case MESA_FORMAT_RGBA_DXT5: /* not supported yet */
+ return GL_FALSE;
+
+ case MESA_FORMAT_RGBA_FLOAT32:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_32_32_32_32_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_RGBA_FLOAT16:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_16_16_16_16_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_RGB_FLOAT32: /* X, Y, Z, ONE */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_32_32_32_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_RGB_FLOAT16:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_16_16_16_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_ALPHA_FLOAT32: /* ZERO, ZERO, ZERO, X */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_32_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_ALPHA_FLOAT16: /* ZERO, ZERO, ZERO, X */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_16_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_LUMINANCE_FLOAT32: /* X, X, X, ONE */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_32_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_LUMINANCE_FLOAT16: /* X, X, X, ONE */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_16_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_32_32_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_16_16_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_32_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_16_FLOAT,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case MESA_FORMAT_Z16:
+ case MESA_FORMAT_X8_Z24:
+ case MESA_FORMAT_S8_Z24:
+ case MESA_FORMAT_Z24_S8:
+ case MESA_FORMAT_Z32:
+ case MESA_FORMAT_S8:
+ CLEARbit(t->SQ_TEX_RESOURCE0, EG_SQ_TEX_RESOURCE_WORD0_0__NDTO_bit);
+ SETfield(t->SQ_TEX_RESOURCE1, ARRAY_1D_TILED_THIN1,
+ EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_mask);
+ switch (mesa_format) {
+ case MESA_FORMAT_Z16:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_16,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+ break;
+ case MESA_FORMAT_X8_Z24:
+ case MESA_FORMAT_S8_Z24:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_24,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+ break;
+ case MESA_FORMAT_Z24_S8:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_24_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+ break;
+ case MESA_FORMAT_Z32:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_32,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+ break;
+ case MESA_FORMAT_S8:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+ break;
+ default:
+ break;
+ };
+ switch (tObj->DepthMode) {
+ case GL_LUMINANCE: /* X, X, X, ONE */
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case GL_INTENSITY: /* X, X, X, X */
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ case GL_ALPHA: /* ZERO, ZERO, ZERO, X */
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ break;
+ default:
+ return GL_FALSE;
+ }
+ break;
+ /* EXT_texture_sRGB */
+ case MESA_FORMAT_SRGBA8:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
+ break;
+ case MESA_FORMAT_SLA8:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
+ break;
+ case MESA_FORMAT_SL8: /* X, X, X, ONE */
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
+ break;
+ default:
+ /* Not supported format */
+ return GL_FALSE;
+ };
+
+ return GL_TRUE;
+}
+
+static GLuint evergreen_translate_shadow_func(GLenum func)
+{
+ switch (func) {
+ case GL_NEVER:
+ return SQ_TEX_DEPTH_COMPARE_NEVER;
+ case GL_LESS:
+ return SQ_TEX_DEPTH_COMPARE_LESS;
+ case GL_LEQUAL:
+ return SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
+ case GL_GREATER:
+ return SQ_TEX_DEPTH_COMPARE_GREATER;
+ case GL_GEQUAL:
+ return SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
+ case GL_NOTEQUAL:
+ return SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
+ case GL_EQUAL:
+ return SQ_TEX_DEPTH_COMPARE_EQUAL;
+ case GL_ALWAYS:
+ return SQ_TEX_DEPTH_COMPARE_ALWAYS;
+ default:
+ WARN_ONCE("Unknown shadow compare function! %d", func);
+ return 0;
+ }
+}
+
+static void evergreenUpdateTexWrap(radeonTexObjPtr t)
+{
+ struct gl_texture_object *tObj = &t->base;
+
+ SETfield(t->SQ_TEX_SAMPLER0, evergreen_translate_wrap_mode(tObj->WrapS),
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
+
+ if (tObj->Target != GL_TEXTURE_1D)
+ {
+ SETfield(t->SQ_TEX_SAMPLER0, evergreen_translate_wrap_mode(tObj->WrapT),
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Y_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Y_mask);
+
+ if (tObj->Target == GL_TEXTURE_3D)
+ SETfield(t->SQ_TEX_SAMPLER0, evergreen_translate_wrap_mode(tObj->WrapR),
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Z_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_Z_mask);
+ }
+}
+
+static void evergreenSetTexDefaultState(radeonTexObjPtr t)
+{
+ /* Init text object to default states. */
+ t->SQ_TEX_RESOURCE0 = 0;
+ t->SQ_TEX_RESOURCE1 = 0;
+ t->SQ_TEX_RESOURCE2 = 0;
+ t->SQ_TEX_RESOURCE3 = 0;
+ t->SQ_TEX_RESOURCE4 = 0;
+ t->SQ_TEX_RESOURCE5 = 0;
+ t->SQ_TEX_RESOURCE6 = 0;
+ t->SQ_TEX_RESOURCE7 = 0;
+
+ SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_2D,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
+
+ CLEARbit(t->SQ_TEX_RESOURCE0, EG_SQ_TEX_RESOURCE_WORD0_0__NDTO_bit);
+
+ SETfield(t->SQ_TEX_RESOURCE1, ARRAY_LINEAR_GENERAL,
+ EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__ARRAY_MODE_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
+ FORMAT_COMP_X_shift, FORMAT_COMP_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
+ FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
+ FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
+ FORMAT_COMP_W_shift, FORMAT_COMP_W_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_NUM_FORMAT_NORM,
+ SQ_TEX_RESOURCE_WORD4_0__NUM_FORMAT_ALL_shift, SQ_TEX_RESOURCE_WORD4_0__NUM_FORMAT_ALL_mask);
+ CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__SRF_MODE_ALL_bit);
+ CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_ENDIAN_NONE,
+ SQ_TEX_RESOURCE_WORD4_0__ENDIAN_SWAP_shift, SQ_TEX_RESOURCE_WORD4_0__ENDIAN_SWAP_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, 0,
+ BASE_LEVEL_shift,
+ BASE_LEVEL_mask); /* mip-maps */
+
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+ SETfield(t->SQ_TEX_RESOURCE7, SQ_TEX_VTX_VALID_TEXTURE,
+ EG_SQ_TEX_RESOURCE_WORD7_0__TYPE_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__TYPE_mask);
+
+ /* Initialize sampler registers */
+ t->SQ_TEX_SAMPLER0 = 0;
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_XY_FILTER_POINT,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_XY_FILTER_POINT,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_Z_FILTER_NONE,
+ EG_SQ_TEX_SAMPLER_WORD0_0__Z_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__Z_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_Z_FILTER_NONE,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_BORDER_COLOR_TRANS_BLACK,
+ EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_mask);
+
+ t->SQ_TEX_SAMPLER1 = 0;
+ SETfield(t->SQ_TEX_SAMPLER1, 0x7ff,
+ EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_shift,
+ EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_mask);
+
+ t->SQ_TEX_SAMPLER2 = 0;
+ SETbit(t->SQ_TEX_SAMPLER2, EG_SQ_TEX_SAMPLER_WORD2_0__TYPE_bit);
+}
+
+static void evergreenSetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy)
+{
+ /* Force revalidation to account for switches from/to mipmapping. */
+ t->validated = GL_FALSE;
+
+ /* Note that EXT_texture_filter_anisotropic is extremely vague about
+ * how anisotropic filtering interacts with the "normal" filter modes.
+ * When anisotropic filtering is enabled, we override min and mag
+ * filter settings completely. This includes driconf's settings.
+ */
+ if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) {
+ /*t->pp_txfilter |= R300_TX_MAG_FILTER_ANISO
+ | R300_TX_MIN_FILTER_ANISO
+ | R300_TX_MIN_FILTER_MIP_LINEAR
+ | aniso_filter(anisotropy);*/
+ radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "Using maximum anisotropy of %f\n", anisotropy);
+ return;
+ }
+
+ switch (minf)
+ {
+ case GL_NEAREST:
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_None,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
+ break;
+ case GL_LINEAR:
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_None,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Point,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Linear,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Point,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MIN_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Linear,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__MIP_FILTER_mask);
+ break;
+ }
+
+ /* Note we don't have 3D mipmaps so only use the mag filter setting
+ * to set the 3D texture filter mode.
+ */
+ switch (magf)
+ {
+ case GL_NEAREST:
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_mask);
+ break;
+ case GL_LINEAR:
+ SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__XY_MAG_FILTER_mask);
+ break;
+ }
+}
+
+static void evergreenSetTexBorderColor(radeonTexObjPtr t, const GLfloat color[4])
+{
+ t->TD_PS_SAMPLER0_BORDER_ALPHA = *((uint32_t*)&(color[3]));
+ t->TD_PS_SAMPLER0_BORDER_RED = *((uint32_t*)&(color[2]));
+ t->TD_PS_SAMPLER0_BORDER_GREEN = *((uint32_t*)&(color[1]));
+ t->TD_PS_SAMPLER0_BORDER_BLUE = *((uint32_t*)&(color[0]));
+
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_BORDER_COLOR_REGISTER,
+ EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__BORDER_COLOR_TYPE_mask);
+}
+
+static void evergreenSetDepthTexMode(struct gl_texture_object *tObj)
+{
+ radeonTexObjPtr t;
+
+ if (!tObj)
+ return;
+
+ t = radeon_tex_obj(tObj);
+
+ if(!evergreenGetTexFormat(tObj, tObj->Image[0][tObj->BaseLevel]->TexFormat))
+ t->validated = GL_FALSE;
+}
+
+static INLINE uint32_t
+EG_S_FIXED(float value, uint32_t frac_bits)
+{
+ return value * (1 << frac_bits);
+}
+
+static GLboolean evergreen_setup_hardware_state(GLcontext * ctx, struct gl_texture_object *texObj, int unit)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ radeonTexObj *t = radeon_tex_obj(texObj);
+ const struct gl_texture_image *firstImage;
+ GLuint uTexelPitch, row_align;
+
+ if (context->radeon.radeonScreen->driScreen->dri2.enabled &&
+ t->image_override &&
+ t->bo)
+ return GL_TRUE;
+
+ firstImage = t->base.Image[0][t->minLod];
+
+ if (!t->image_override) {
+ if (!evergreenGetTexFormat(texObj, firstImage->TexFormat)) {
+ radeon_warning("unsupported texture format in %s\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ }
+ }
+
+ switch (texObj->Target)
+ {
+ case GL_TEXTURE_1D:
+ SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_1D,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
+ SETfield(t->SQ_TEX_RESOURCE1, 0,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask);
+ break;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE_NV:
+ SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_2D,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
+ SETfield(t->SQ_TEX_RESOURCE1, 0,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask);
+ break;
+ case GL_TEXTURE_3D:
+ SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_3D,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
+ SETfield(t->SQ_TEX_RESOURCE1, (firstImage->Depth - 1), // ???
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask);
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_CUBEMAP,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__DIM_mask);
+ SETfield(t->SQ_TEX_RESOURCE1, 0,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_DEPTH_mask);
+ break;
+ default:
+ radeon_error("unexpected texture target type in %s\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ row_align = context->radeon.texture_row_align - 1;
+ uTexelPitch = (_mesa_format_row_stride(firstImage->TexFormat, firstImage->Width) + row_align) & ~row_align;
+ uTexelPitch = uTexelPitch / _mesa_get_format_bytes(firstImage->TexFormat);
+ uTexelPitch = (uTexelPitch + R700_TEXEL_PITCH_ALIGNMENT_MASK)
+ & ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
+
+ /* min pitch is 8 */
+ if (uTexelPitch < 8)
+ uTexelPitch = 8;
+
+ SETfield(t->SQ_TEX_RESOURCE0, (uTexelPitch/8)-1,
+ EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_mask);
+ SETfield(t->SQ_TEX_RESOURCE0, firstImage->Width - 1,
+ EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_mask);
+ SETfield(t->SQ_TEX_RESOURCE1, firstImage->Height - 1,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_mask);
+
+ t->SQ_TEX_RESOURCE2 = get_base_teximage_offset(t) / 256;
+
+ t->SQ_TEX_RESOURCE3 = radeon_miptree_image_offset(t->mt, 0, t->minLod + 1) / 256;
+
+ SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask);
+ SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask);
+
+ SETfield(t->SQ_TEX_SAMPLER1,
+ EG_S_FIXED(CLAMP(t->base.MinLod - t->minLod, 0, 15), 6),
+ EG_SQ_TEX_SAMPLER_WORD1_0__MIN_LOD_shift,
+ EG_SQ_TEX_SAMPLER_WORD1_0__MIN_LOD_mask);
+ SETfield(t->SQ_TEX_SAMPLER1,
+ EG_S_FIXED(CLAMP(t->base.MaxLod - t->minLod, 0, 15), 6),
+ EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_shift,
+ EG_SQ_TEX_SAMPLER_WORD1_0__MAX_LOD_mask);
+ SETfield(t->SQ_TEX_SAMPLER2,
+ EG_S_FIXED(CLAMP(ctx->Texture.Unit[unit].LodBias + t->base.LodBias, -16, 16), 6),
+ EG_SQ_TEX_SAMPLER_WORD2_0__LOD_BIAS_shift,
+ EG_SQ_TEX_SAMPLER_WORD2_0__LOD_BIAS_mask);
+
+ if(texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB)
+ {
+ SETfield(t->SQ_TEX_SAMPLER0, evergreen_translate_shadow_func(texObj->CompareFunc),
+ EG_SQ_TEX_SAMPLER_WORD0_0__DCF_shift,
+ EG_SQ_TEX_SAMPLER_WORD0_0__DCF_mask);
+ }
+ else
+ {
+ CLEARfield(t->SQ_TEX_SAMPLER0, EG_SQ_TEX_SAMPLER_WORD0_0__DCF_mask);
+ }
+
+ return GL_TRUE;
+}
+
+void evergreenSetTexOffset(__DRIcontext * pDRICtx, GLint texname,
+ unsigned long long offset, GLint depth, GLuint pitch)
+{
+ context_t *rmesa = pDRICtx->driverPrivate;
+ struct gl_texture_object *tObj =
+ _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
+ radeonTexObjPtr t = radeon_tex_obj(tObj);
+ const struct gl_texture_image *firstImage;
+ uint32_t pitch_val, size, row_align;
+
+ if (!tObj)
+ return;
+
+ t->image_override = GL_TRUE;
+
+ if (!offset)
+ return;
+
+ firstImage = t->base.Image[0][t->minLod];
+ row_align = rmesa->radeon.texture_row_align - 1;
+ size = ((_mesa_format_row_stride(firstImage->TexFormat, firstImage->Width) + row_align) & ~row_align) * firstImage->Height;
+ if (t->bo) {
+ radeon_bo_unref(t->bo);
+ t->bo = NULL;
+ }
+ t->bo = radeon_legacy_bo_alloc_fake(rmesa->radeon.radeonScreen->bom, size, offset);
+ t->override_offset = offset;
+ pitch_val = pitch;
+ switch (depth) {
+ case 32:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ pitch_val /= 4;
+ break;
+ case 24:
+ default:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ pitch_val /= 4;
+ break;
+ case 16:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_5_6_5,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ pitch_val /= 2;
+ break;
+ }
+
+ pitch_val = (pitch_val + R700_TEXEL_PITCH_ALIGNMENT_MASK)
+ & ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
+
+ /* min pitch is 8 */
+ if (pitch_val < 8)
+ pitch_val = 8;
+
+ SETfield(t->SQ_TEX_RESOURCE0, (pitch_val/8)-1,
+ EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_mask);
+}
+
+void evergreenSetTexBuffer(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, __DRIdrawable *dPriv)
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ struct radeon_renderbuffer *rb;
+ radeon_texture_image *rImage;
+ radeonContextPtr radeon;
+ context_t *rmesa;
+ struct radeon_framebuffer *rfb;
+ radeonTexObjPtr t;
+ uint32_t pitch_val;
+ uint32_t internalFormat, type, format;
+
+ type = GL_BGRA;
+ format = GL_UNSIGNED_BYTE;
+ internalFormat = (glx_texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
+
+ radeon = pDRICtx->driverPrivate;
+ rmesa = pDRICtx->driverPrivate;
+
+ rfb = dPriv->driverPrivate;
+ texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
+ texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
+ texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
+
+ rImage = get_radeon_texture_image(texImage);
+ t = radeon_tex_obj(texObj);
+ if (t == NULL) {
+ return;
+ }
+
+ radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
+ rb = rfb->color_rb[0];
+ if (rb->bo == NULL) {
+ /* Failed to BO for the buffer */
+ return;
+ }
+
+ _mesa_lock_texture(radeon->glCtx, texObj);
+ if (t->bo) {
+ radeon_bo_unref(t->bo);
+ t->bo = NULL;
+ }
+ if (rImage->bo) {
+ radeon_bo_unref(rImage->bo);
+ rImage->bo = NULL;
+ }
+
+ radeon_miptree_unreference(&t->mt);
+ radeon_miptree_unreference(&rImage->mt);
+
+ _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
+ rb->base.Width, rb->base.Height, 1, 0, rb->cpp);
+ texImage->RowStride = rb->pitch / rb->cpp;
+
+ rImage->bo = rb->bo;
+ radeon_bo_ref(rImage->bo);
+ t->bo = rb->bo;
+ radeon_bo_ref(t->bo);
+ t->image_override = GL_TRUE;
+ t->override_offset = 0;
+ pitch_val = rb->pitch;
+ switch (rb->cpp) {
+ case 4:
+ if (glx_texture_format == __DRI_TEXTURE_FORMAT_RGB) {
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ } else {
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ }
+ pitch_val /= 4;
+ break;
+ case 3:
+ default:
+ // FMT_8_8_8 ???
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_8_8_8_8,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ pitch_val /= 4;
+ break;
+ case 2:
+ SETfield(t->SQ_TEX_RESOURCE7, FMT_5_6_5,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_shift,
+ EG_SQ_TEX_RESOURCE_WORD7_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ pitch_val /= 2;
+ break;
+ }
+
+ pitch_val = (pitch_val + R700_TEXEL_PITCH_ALIGNMENT_MASK)
+ & ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
+
+ /* min pitch is 8 */
+ if (pitch_val < 8)
+ pitch_val = 8;
+
+ SETfield(t->SQ_TEX_RESOURCE0, (pitch_val/8)-1,
+ EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__PITCH_mask);
+ SETfield(t->SQ_TEX_RESOURCE0, rb->base.Width - 1,
+ EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_shift,
+ EG_SQ_TEX_RESOURCE_WORD0_0__TEX_WIDTH_mask);
+ SETfield(t->SQ_TEX_RESOURCE1, rb->base.Height - 1,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_shift,
+ EG_SQ_TEX_RESOURCE_WORD1_0__TEX_HEIGHT_mask);
+
+ t->validated = GL_TRUE;
+ _mesa_unlock_texture(radeon->glCtx, texObj);
+ return;
+}
+
+void evergreenUpdateTextureState(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT * evergreen = GET_EVERGREEN_CHIP(context);
+ struct gl_texture_unit *texUnit;
+ struct radeon_tex_obj *t;
+ GLuint unit;
+
+ EVERGREEN_STATECHANGE(context, tx);
+
+ for (unit = 0; unit < R700_MAX_TEXTURE_UNITS; unit++) {
+ texUnit = &ctx->Texture.Unit[unit];
+ t = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
+ evergreen->textures[unit] = NULL;
+ if (texUnit->_ReallyEnabled) {
+ if (!t)
+ continue;
+ evergreen->textures[unit] = t;
+ }
+ }
+}
+
+static GLboolean evergreen_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj, int unit)
+{
+ radeonTexObj *t = radeon_tex_obj(texObj);
+
+ if (!radeon_validate_texture_miptree(ctx, texObj))
+ return GL_FALSE;
+
+ /* Configure the hardware registers (more precisely, the cached version
+ * of the hardware registers). */
+ if (!evergreen_setup_hardware_state(ctx, texObj, unit))
+ return GL_FALSE;
+
+ t->validated = GL_TRUE;
+ return GL_TRUE;
+}
+
+GLboolean evergreenValidateBuffers(GLcontext * ctx)
+{
+ context_t *rmesa = EVERGREEN_CONTEXT(ctx);
+ struct radeon_renderbuffer *rrb;
+ struct radeon_bo *pbo;
+ int i;
+ int ret;
+
+ radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
+
+ rrb = radeon_get_colorbuffer(&rmesa->radeon);
+ /* color buffer */
+ if (rrb && rrb->bo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ rrb->bo, 0,
+ RADEON_GEM_DOMAIN_VRAM);
+ }
+
+ /* depth buffer */
+ rrb = radeon_get_depthbuffer(&rmesa->radeon);
+ if (rrb && rrb->bo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ rrb->bo, 0,
+ RADEON_GEM_DOMAIN_VRAM);
+ }
+
+ for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
+ radeonTexObj *t;
+
+ if (!ctx->Texture.Unit[i]._ReallyEnabled)
+ continue;
+
+ if (!evergreen_validate_texture(ctx, ctx->Texture.Unit[i]._Current, i)) {
+ radeon_warning("failed to validate texture for unit %d.\n", i);
+ }
+ t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
+ if (t->image_override && t->bo)
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ t->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ else if (t->mt->bo)
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs,
+ t->mt->bo,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+ }
+
+ pbo = (struct radeon_bo *)evergreenGetActiveFpShaderBo(ctx);
+ if (pbo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+
+ pbo = (struct radeon_bo *)evergreenGetActiveVpShaderBo(ctx);
+ if (pbo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+
+ pbo = (struct radeon_bo *)evergreenGetActiveFpShaderConstBo(ctx);
+ if (pbo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+
+ pbo = (struct radeon_bo *)evergreenGetActiveVpShaderConstBo(ctx);
+ if (pbo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
+ if (ret)
+ return GL_FALSE;
+ return GL_TRUE;
+}
+
+static struct gl_texture_object *evergreenNewTextureObject(GLcontext * ctx,
+ GLuint name,
+ GLenum target)
+{
+ context_t* rmesa = EVERGREEN_CONTEXT(ctx);
+ radeonTexObj * t = CALLOC_STRUCT(radeon_tex_obj);
+
+
+ radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
+ "%s( %p (target = %s) )\n", __FUNCTION__,
+ t, _mesa_lookup_enum_by_nr(target));
+
+ _mesa_initialize_texture_object(&t->base, name, target);
+ t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
+
+ evergreenSetTexDefaultState(t);
+ evergreenUpdateTexWrap(t);
+ evergreenSetTexFilter(t, t->base.MinFilter, t->base.MagFilter, t->base.MaxAnisotropy);
+ evergreenSetTexBorderColor(t, t->base.BorderColor.f);
+
+ return &t->base;
+}
+
+static void evergreenDeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
+{
+ context_t * rmesa = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT * evergreen = GET_EVERGREEN_CHIP(rmesa);
+ radeonTexObj* t = radeon_tex_obj(texObj);
+
+ radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
+ "%s( %p (target = %s) )\n", __FUNCTION__,
+ (void *)texObj,
+ _mesa_lookup_enum_by_nr(texObj->Target));
+
+ if (rmesa) {
+ int i;
+ radeon_firevertices(&rmesa->radeon);
+
+ for(i = 0; i < R700_MAX_TEXTURE_UNITS; ++i)
+ if (evergreen->textures[i] == t)
+ evergreen->textures[i] = 0;
+ }
+
+ if (t->bo) {
+ radeon_bo_unref(t->bo);
+ t->bo = NULL;
+ }
+
+ radeon_miptree_unreference(&t->mt);
+
+ _mesa_delete_texture_object(ctx, texObj);
+}
+
+static void evergreenTexParameter(GLcontext * ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat * params)
+{
+ radeonTexObj* t = radeon_tex_obj(texObj);
+ GLenum baseFormat;
+
+ radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_VERBOSE,
+ "%s( %s )\n", __FUNCTION__,
+ _mesa_lookup_enum_by_nr(pname));
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ evergreenSetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ evergreenUpdateTexWrap(t);
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ evergreenSetTexBorderColor(t, texObj->BorderColor.f);
+ break;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ t->validated = GL_FALSE;
+ break;
+
+ case GL_DEPTH_TEXTURE_MODE:
+ if (!texObj->Image[0][texObj->BaseLevel])
+ return;
+ baseFormat = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
+ if (baseFormat == GL_DEPTH_COMPONENT ||
+ baseFormat == GL_DEPTH_STENCIL) {
+ evergreenSetDepthTexMode(texObj);
+ break;
+ } else {
+ /* If the texture isn't a depth texture, changing this
+ * state won't cause any changes to the hardware.
+ * Don't force a flush of texture state.
+ */
+ return;
+ }
+
+ default:
+ return;
+ }
+}
+
+void evergreenInitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions)
+{
+ /* Note: we only plug in the functions we implement in the driver
+ * since _mesa_init_driver_functions() was already called.
+ */
+ functions->NewTextureImage = radeonNewTextureImage;
+ functions->FreeTexImageData = radeonFreeTexImageData;
+ functions->MapTexture = radeonMapTexture;
+ functions->UnmapTexture = radeonUnmapTexture;
+
+ functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa;
+ functions->TexImage1D = radeonTexImage1D;
+ functions->TexImage2D = radeonTexImage2D;
+ functions->TexImage3D = radeonTexImage3D;
+ functions->TexSubImage1D = radeonTexSubImage1D;
+ functions->TexSubImage2D = radeonTexSubImage2D;
+ functions->TexSubImage3D = radeonTexSubImage3D;
+ functions->GetTexImage = radeonGetTexImage;
+ functions->GetCompressedTexImage = radeonGetCompressedTexImage;
+ functions->NewTextureObject = evergreenNewTextureObject;
+ functions->DeleteTexture = evergreenDeleteTexture;
+ functions->IsTextureResident = driIsTextureResident;
+
+ functions->TexParameter = evergreenTexParameter;
+
+ functions->CompressedTexImage2D = radeonCompressedTexImage2D;
+ functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
+
+ if (radeon->radeonScreen->kernel_mm) {
+ functions->CopyTexImage2D = radeonCopyTexImage2D;
+ functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
+ }
+
+ functions->GenerateMipmap = radeonGenerateMipmap;
+
+ driInitTextureFormats();
+}
diff --git a/src/mesa/slang/slang_log.h b/src/mesa/drivers/dri/r600/evergreen_tex.h
index 544a26654e7..b43508a9eab 100644
--- a/src/mesa/slang/slang_log.h
+++ b/src/mesa/drivers/dri/r600/evergreen_tex.h
@@ -1,8 +1,5 @@
/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -17,43 +14,25 @@
* 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
-#ifndef SLANG_LOG_H
-#define SLANG_LOG_H
-
-
-#include "main/glheader.h"
-
-typedef struct slang_info_log_
-{
- char *text;
- GLboolean dont_free_text;
- GLboolean error_flag;
-} slang_info_log;
-
-
-extern void
-slang_info_log_construct(slang_info_log *);
-
-extern void
-slang_info_log_destruct(slang_info_log *);
-
-extern int
-slang_info_log_print(slang_info_log *, const char *, ...);
-
-extern int
-slang_info_log_error(slang_info_log *, const char *, ...);
-
-extern int
-slang_info_log_warning(slang_info_log *, const char *, ...);
+#ifndef _EVERGREEN_TEX_H_
+#define _EVERGREEN_TEX_H_
-extern void
-slang_info_log_memory(slang_info_log *);
+extern GLboolean evergreenValidateBuffers(GLcontext * ctx);
+extern void evergreenUpdateTextureState(GLcontext * ctx);
+extern void evergreenInitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions);
+extern void evergreenSetTexOffset(__DRIcontext * pDRICtx, GLint texname,
+ unsigned long long offset, GLint depth, GLuint pitch);
+extern void evergreenSetTexBuffer(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, __DRIdrawable *dPriv);
-#endif /* SLANG_LOG_H */
+#endif /* _EVERGREEN_TEX_H_ */
diff --git a/src/mesa/drivers/dri/r600/evergreen_vertprog.c b/src/mesa/drivers/dri/r600/evergreen_vertprog.c
new file mode 100644
index 00000000000..4f3db00c7d2
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_vertprog.c
@@ -0,0 +1,736 @@
+/*
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+
+#include "tnl/t_context.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+
+#include "radeon_debug.h"
+#include "r600_context.h"
+#include "r600_cmdbuf.h"
+#include "r600_emit.h"
+#include "program/programopt.h"
+
+#include "evergreen_vertprog.h"
+
+unsigned int evergreen_Map_Vertex_Output(r700_AssemblerBase *pAsm,
+ struct gl_vertex_program *mesa_vp,
+ unsigned int unStart)
+{
+ unsigned int i;
+ unsigned int unBit;
+ unsigned int unTotal = unStart;
+
+ //!!!!!!! THE ORDER MATCH FS INPUT
+
+ unBit = 1 << VERT_RESULT_HPOS;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_HPOS] = unTotal++;
+ }
+
+ unBit = 1 << VERT_RESULT_COL0;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_COL0] = unTotal++;
+ }
+
+ unBit = 1 << VERT_RESULT_COL1;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_COL1] = unTotal++;
+ }
+
+ //TODO : dealing back face.
+ unBit = 1 << VERT_RESULT_BFC0;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_BFC0] = unTotal++;
+ }
+
+ unBit = 1 << VERT_RESULT_BFC1;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_BFC1] = unTotal++;
+ }
+
+ //TODO : dealing fog.
+ unBit = 1 << VERT_RESULT_FOGC;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_FOGC] = unTotal++;
+ }
+
+ //TODO : dealing point size.
+ unBit = 1 << VERT_RESULT_PSIZ;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_PSIZ] = unTotal++;
+ }
+
+ for(i=0; i<8; i++)
+ {
+ unBit = 1 << (VERT_RESULT_TEX0 + i);
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_TEX0 + i] = unTotal++;
+ }
+ }
+
+ for(i=VERT_RESULT_VAR0; i<VERT_RESULT_MAX; i++)
+ {
+ unBit = 1 << i;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[i] = unTotal++;
+ }
+ }
+
+ return (unTotal - unStart);
+}
+
+unsigned int evergreen_Map_Vertex_Input(r700_AssemblerBase *pAsm,
+ struct gl_vertex_program *mesa_vp,
+ unsigned int unStart)
+{
+ int i;
+ unsigned int unBit;
+ unsigned int unTotal = unStart;
+ for(i=0; i<VERT_ATTRIB_MAX; i++)
+ {
+ unBit = 1 << i;
+ if(mesa_vp->Base.InputsRead & unBit)
+ {
+ pAsm->ucVP_AttributeMap[i] = unTotal++;
+ }
+ }
+ return (unTotal - unStart);
+}
+
+GLboolean evergreen_Process_Vertex_Program_Vfetch_Instructions(
+ struct evergreen_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp)
+{
+ int i;
+ unsigned int unBit;
+ VTX_FETCH_METHOD vtxFetchMethod;
+ vtxFetchMethod.bEnableMini = GL_FALSE;
+ vtxFetchMethod.mega_fetch_remainder = 0;
+
+ for(i=0; i<VERT_ATTRIB_MAX; i++)
+ {
+ unBit = 1 << i;
+ if(mesa_vp->Base.InputsRead & unBit)
+ {
+ assemble_vfetch_instruction(&vp->r700AsmCode,
+ i,
+ vp->r700AsmCode.ucVP_AttributeMap[i],
+ vp->aos_desc[i].size,
+ vp->aos_desc[i].type,
+ &vtxFetchMethod);
+ }
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean evergreen_Process_Vertex_Program_Vfetch_Instructions2(
+ GLcontext *ctx,
+ struct evergreen_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp)
+{
+ int i;
+ context_t *context = R700_CONTEXT(ctx);
+
+ VTX_FETCH_METHOD vtxFetchMethod;
+ vtxFetchMethod.bEnableMini = GL_FALSE;
+ vtxFetchMethod.mega_fetch_remainder = 0;
+
+ for(i=0; i<context->nNumActiveAos; i++)
+ {
+ EG_assemble_vfetch_instruction(&vp->r700AsmCode,
+ vp->r700AsmCode.ucVP_AttributeMap[context->stream_desc[i].element],
+ context->stream_desc[i].type,
+ context->stream_desc[i].size,
+ context->stream_desc[i].element,
+ context->stream_desc[i]._signed,
+ context->stream_desc[i].normalize,
+ context->stream_desc[i].format,
+ &vtxFetchMethod);
+ }
+
+ return GL_TRUE;
+}
+
+void evergreen_Map_Vertex_Program(GLcontext *ctx,
+ struct evergreen_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp)
+{
+ GLuint ui;
+ r700_AssemblerBase *pAsm = &(vp->r700AsmCode);
+ unsigned int num_inputs;
+
+ // R0 will always be used for index into vertex buffer
+ pAsm->number_used_registers = 1;
+ pAsm->starting_vfetch_register_number = pAsm->number_used_registers;
+
+ // Map Inputs: Add 1 to mapping since R0 is used for index
+ num_inputs = evergreen_Map_Vertex_Input(pAsm, mesa_vp, pAsm->number_used_registers);
+ pAsm->number_used_registers += num_inputs;
+
+ // Create VFETCH instructions for inputs
+ if (GL_TRUE != evergreen_Process_Vertex_Program_Vfetch_Instructions2(ctx, vp, mesa_vp) )
+ {
+ radeon_error("Calling evergreen_Process_Vertex_Program_Vfetch_Instructions2 return error. \n");
+ return;
+ }
+
+ // Map Outputs
+ pAsm->number_of_exports = evergreen_Map_Vertex_Output(pAsm, mesa_vp, pAsm->number_used_registers);
+
+ pAsm->starting_export_register_number = pAsm->number_used_registers;
+
+ pAsm->number_used_registers += pAsm->number_of_exports;
+
+ pAsm->pucOutMask = (unsigned char*) MALLOC(pAsm->number_of_exports);
+
+ for(ui=0; ui<pAsm->number_of_exports; ui++)
+ {
+ pAsm->pucOutMask[ui] = 0x0;
+ }
+
+ /* Map temporary registers (GPRs) */
+ pAsm->starting_temp_register_number = pAsm->number_used_registers;
+
+ if(mesa_vp->Base.NumNativeTemporaries >= mesa_vp->Base.NumTemporaries)
+ { /* arb uses NumNativeTemporaries */
+ pAsm->number_used_registers += mesa_vp->Base.NumNativeTemporaries;
+ }
+ else
+ { /* fix func t_vp uses NumTemporaries */
+ pAsm->number_used_registers += mesa_vp->Base.NumTemporaries;
+ }
+
+ pAsm->flag_reg_index = pAsm->number_used_registers++;
+
+ pAsm->uFirstHelpReg = pAsm->number_used_registers;
+}
+
+GLboolean evergreen_Find_Instruction_Dependencies_vp(struct evergreen_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp)
+{
+ GLuint i, j;
+ GLint * puiTEMPwrites;
+ struct prog_instruction *pILInst;
+ InstDeps *pInstDeps;
+
+ puiTEMPwrites = (GLint*) MALLOC(sizeof(GLuint)*mesa_vp->Base.NumTemporaries);
+ for(i=0; i<mesa_vp->Base.NumTemporaries; i++)
+ {
+ puiTEMPwrites[i] = -1;
+ }
+
+ pInstDeps = (InstDeps*)MALLOC(sizeof(InstDeps)*mesa_vp->Base.NumInstructions);
+
+ for(i=0; i<mesa_vp->Base.NumInstructions; i++)
+ {
+ pInstDeps[i].nDstDep = -1;
+ pILInst = &(mesa_vp->Base.Instructions[i]);
+
+ //Dst
+ if(pILInst->DstReg.File == PROGRAM_TEMPORARY)
+ {
+ //Set lastwrite for the temp
+ puiTEMPwrites[pILInst->DstReg.Index] = i;
+ }
+
+ //Src
+ for(j=0; j<3; j++)
+ {
+ if(pILInst->SrcReg[j].File == PROGRAM_TEMPORARY)
+ {
+ //Set dep.
+ pInstDeps[i].nSrcDeps[j] = puiTEMPwrites[pILInst->SrcReg[j].Index];
+ }
+ else
+ {
+ pInstDeps[i].nSrcDeps[j] = -1;
+ }
+ }
+ }
+
+ vp->r700AsmCode.pInstDeps = pInstDeps;
+
+ FREE(puiTEMPwrites);
+
+ return GL_TRUE;
+}
+
+struct evergreen_vertex_program* evergreenTranslateVertexShader(GLcontext *ctx,
+ struct gl_vertex_program *mesa_vp)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+
+ struct evergreen_vertex_program *vp;
+ unsigned int i;
+
+ vp = calloc(1, sizeof(*vp));
+ vp->mesa_program = _mesa_clone_vertex_program(ctx, mesa_vp);
+
+ vp->constbo0 = NULL;
+
+ if (mesa_vp->IsPositionInvariant)
+ {
+ _mesa_insert_mvp_code(ctx, vp->mesa_program);
+ }
+
+ for(i=0; i<context->nNumActiveAos; i++)
+ {
+ vp->aos_desc[i].size = context->stream_desc[i].size;
+ vp->aos_desc[i].stride = context->stream_desc[i].stride;
+ vp->aos_desc[i].type = context->stream_desc[i].type;
+ vp->aos_desc[i].format = context->stream_desc[i].format;
+ }
+
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ {
+ vp->r700AsmCode.bR6xx = 1;
+ }
+
+ //Init_Program
+ Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) );
+
+ vp->r700AsmCode.bUseMemConstant = GL_TRUE;
+ vp->r700AsmCode.unAsic = 8;
+
+ evergreen_Map_Vertex_Program(ctx, vp, vp->mesa_program );
+
+ if(GL_FALSE == evergreen_Find_Instruction_Dependencies_vp(vp, vp->mesa_program))
+ {
+ return NULL;
+ }
+
+ InitShaderProgram(&(vp->r700AsmCode));
+
+ for(i=0; i < MAX_SAMPLERS; i++)
+ {
+ vp->r700AsmCode.SamplerUnits[i] = vp->mesa_program->Base.SamplerUnits[i];
+ }
+
+ vp->r700AsmCode.unCurNumILInsts = vp->mesa_program->Base.NumInstructions;
+
+ if(GL_FALSE == AssembleInstr(0,
+ 0,
+ vp->mesa_program->Base.NumInstructions,
+ &(vp->mesa_program->Base.Instructions[0]),
+ &(vp->r700AsmCode)) )
+ {
+ return NULL;
+ }
+
+ if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), vp->mesa_program->Base.OutputsWritten) )
+ {
+ return NULL;
+ }
+
+ if( GL_FALSE == RelocProgram(&(vp->r700AsmCode), &(vp->mesa_program->Base)) )
+ {
+ return GL_FALSE;
+ }
+
+ vp->r700Shader.nRegs = (vp->r700AsmCode.number_used_registers == 0) ? 0
+ : (vp->r700AsmCode.number_used_registers - 1);
+
+ vp->r700Shader.nParamExports = vp->r700AsmCode.number_of_exports;
+
+ vp->translated = GL_TRUE;
+
+ return vp;
+}
+
+void evergreenSelectVertexShader(GLcontext *ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ struct evergreen_vertex_program_cont *vpc;
+ struct evergreen_vertex_program *vp;
+ unsigned int i;
+ GLboolean match;
+ GLbitfield InputsRead;
+
+ vpc = (struct evergreen_vertex_program_cont *)ctx->VertexProgram._Current;
+
+ InputsRead = vpc->mesa_program.Base.InputsRead;
+ if (vpc->mesa_program.IsPositionInvariant)
+ {
+ InputsRead |= VERT_BIT_POS;
+ }
+
+ for (vp = vpc->progs; vp; vp = vp->next)
+ {
+ match = GL_TRUE;
+ for(i=0; i<context->nNumActiveAos; i++)
+ {
+ if (vp->aos_desc[i].size != context->stream_desc[i].size ||
+ vp->aos_desc[i].format != context->stream_desc[i].format)
+ {
+ match = GL_FALSE;
+ break;
+ }
+ }
+ if (match)
+ {
+ context->selected_vp = vp;
+ return;
+ }
+ }
+
+ vp = evergreenTranslateVertexShader(ctx, &(vpc->mesa_program));
+ if(!vp)
+ {
+ radeon_error("Failed to translate vertex shader. \n");
+ return;
+ }
+ vp->next = vpc->progs;
+ vpc->progs = vp;
+ context->selected_vp = vp;
+ return;
+}
+
+int evergreen_getTypeSize(GLenum type)
+{
+ switch (type)
+ {
+ case GL_DOUBLE:
+ return sizeof(GLdouble);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ case GL_SHORT:
+ return sizeof(GLshort);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_BYTE:
+ return sizeof(GLbyte);
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+static void evergreenTranslateAttrib(GLcontext *ctx, GLuint unLoc, int count, const struct gl_client_array *input)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+
+ StreamDesc * pStreamDesc = &(context->stream_desc[context->nNumActiveAos]);
+
+ GLuint stride;
+
+ stride = (input->StrideB == 0) ? evergreen_getTypeSize(input->Type) * input->Size
+ : input->StrideB;
+
+ if (input->Type == GL_DOUBLE || input->Type == GL_UNSIGNED_INT || input->Type == GL_INT ||
+#if MESA_BIG_ENDIAN
+ evergreen_getTypeSize(input->Type) != 4 ||
+#endif
+ stride < 4)
+ {
+ pStreamDesc->type = GL_FLOAT;
+
+ if (input->StrideB == 0)
+ {
+ pStreamDesc->stride = 0;
+ }
+ else
+ {
+ pStreamDesc->stride = sizeof(GLfloat) * input->Size;
+ }
+ pStreamDesc->dwords = input->Size;
+ pStreamDesc->is_named_bo = GL_FALSE;
+ }
+ else
+ {
+ pStreamDesc->type = input->Type;
+ pStreamDesc->dwords = (evergreen_getTypeSize(input->Type) * input->Size + 3)/ 4;
+ if (!input->BufferObj->Name)
+ {
+ if (input->StrideB == 0)
+ {
+ pStreamDesc->stride = 0;
+ }
+ else
+ {
+ pStreamDesc->stride = (evergreen_getTypeSize(pStreamDesc->type) * input->Size + 3) & ~3;
+ }
+
+ pStreamDesc->is_named_bo = GL_FALSE;
+ }
+ }
+
+ pStreamDesc->size = input->Size;
+ pStreamDesc->dst_loc = context->nNumActiveAos;
+ pStreamDesc->element = unLoc;
+ pStreamDesc->format = input->Format;
+
+ switch (pStreamDesc->type)
+ { //GetSurfaceFormat
+ case GL_FLOAT:
+ pStreamDesc->_signed = 0;
+ pStreamDesc->normalize = GL_FALSE;
+ break;
+ case GL_SHORT:
+ pStreamDesc->_signed = 1;
+ pStreamDesc->normalize = input->Normalized;
+ break;
+ case GL_BYTE:
+ pStreamDesc->_signed = 1;
+ pStreamDesc->normalize = input->Normalized;
+ break;
+ case GL_UNSIGNED_SHORT:
+ pStreamDesc->_signed = 0;
+ pStreamDesc->normalize = input->Normalized;
+ break;
+ case GL_UNSIGNED_BYTE:
+ pStreamDesc->_signed = 0;
+ pStreamDesc->normalize = input->Normalized;
+ break;
+ default:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_DOUBLE:
+ assert(0);
+ break;
+ }
+ context->nNumActiveAos++;
+}
+
+void evergreenSetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ struct evergreen_vertex_program *vpc
+ = (struct evergreen_vertex_program *)ctx->VertexProgram._Current;
+
+ struct gl_vertex_program * mesa_vp = (struct gl_vertex_program *)&(vpc->mesa_program);
+ unsigned int unLoc = 0;
+ unsigned int unBit = mesa_vp->Base.InputsRead;
+ context->nNumActiveAos = 0;
+
+ if (mesa_vp->IsPositionInvariant)
+ {
+ unBit |= VERT_BIT_POS;
+ }
+
+ while(unBit)
+ {
+ if(unBit & 1)
+ {
+ evergreenTranslateAttrib(ctx, unLoc, count, arrays[unLoc]);
+ }
+
+ unBit >>= 1;
+ ++unLoc;
+ }
+ context->radeon.tcl.aos_count = context->nNumActiveAos;
+}
+
+void * evergreenGetActiveVpShaderBo(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ struct evergreen_vertex_program *vp = context->selected_vp;;
+
+ if (vp)
+ return vp->shaderbo;
+ else
+ return NULL;
+}
+
+void * evergreenGetActiveVpShaderConstBo(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ struct evergreen_vertex_program *vp = context->selected_vp;;
+
+ if (vp)
+ return vp->constbo0;
+ else
+ return NULL;
+}
+
+GLboolean evergreenSetupVertexProgram(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct evergreen_vertex_program *vp = context->selected_vp;
+
+ if(GL_FALSE == vp->loaded)
+ {
+ if(vp->r700Shader.bNeedsAssembly == GL_TRUE)
+ {
+ Assemble( &(vp->r700Shader) );
+ }
+
+ /* Load vp to gpu */
+ r600EmitShader(ctx,
+ &(vp->shaderbo),
+ (GLvoid *)(vp->r700Shader.pProgram),
+ vp->r700Shader.uShaderBinaryDWORDSize,
+ "VS");
+
+ vp->loaded = GL_TRUE;
+ }
+
+ EVERGREEN_STATECHANGE(context, vs);
+
+ /* TODO : enable this after MemUse fixed *=
+ (context->chipobj.MemUse)(context, vp->shadercode.buf->id);
+ */
+
+ evergreen->SQ_PGM_RESOURCES_VS.u32All = 0;
+ SETbit(evergreen->SQ_PGM_RESOURCES_VS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
+
+ evergreen->vs.SQ_ALU_CONST_CACHE_VS_0.u32All = 0; /* set from buffer object. */
+
+ evergreen->vs.SQ_PGM_START_VS.u32All = 0;
+
+ SETfield(evergreen->SQ_PGM_RESOURCES_VS.u32All, vp->r700Shader.nRegs + 1,
+ NUM_GPRS_shift, NUM_GPRS_mask);
+
+ if(vp->r700Shader.uStackSize) /* we don't use branch for now, it should be zero. */
+ {
+ SETfield(evergreen->SQ_PGM_RESOURCES_VS.u32All, vp->r700Shader.uStackSize,
+ STACK_SIZE_shift, STACK_SIZE_mask);
+ }
+
+ EVERGREEN_STATECHANGE(context, spi);
+
+ SETfield(evergreen->SPI_VS_OUT_CONFIG.u32All,
+ vp->r700Shader.nParamExports ? (vp->r700Shader.nParamExports - 1) : 0,
+ VS_EXPORT_COUNT_shift, VS_EXPORT_COUNT_mask);
+ SETfield(evergreen->SPI_PS_IN_CONTROL_0.u32All, vp->r700Shader.nParamExports,
+ NUM_INTERP_shift, NUM_INTERP_mask);
+
+ /*
+ SETbit(evergreen->SPI_PS_IN_CONTROL_0.u32All, PERSP_GRADIENT_ENA_bit);
+ CLEARbit(evergreen->SPI_PS_IN_CONTROL_0.u32All, LINEAR_GRADIENT_ENA_bit);
+ */
+
+ return GL_TRUE;
+}
+
+GLboolean evergreenSetupVPconstants(GLcontext * ctx)
+{
+ context_t *context = EVERGREEN_CONTEXT(ctx);
+ EVERGREEN_CHIP_CONTEXT *evergreen = GET_EVERGREEN_CHIP(context);
+ struct evergreen_vertex_program *vp = context->selected_vp;
+
+ struct gl_program_parameter_list *paramList;
+ unsigned int unNumParamData;
+ unsigned int ui;
+
+ /* sent out shader constants. */
+ paramList = vp->mesa_program->Base.Parameters;
+
+ if(NULL != paramList) {
+ /* vp->mesa_program was cloned, not updated by glsl shader api. */
+ /* _mesa_reference_program has already checked glsl shProg is ok and set ctx->VertexProgem._Current */
+ /* so, use ctx->VertexProgem._Current */
+ struct gl_program_parameter_list *paramListOrginal =
+ ctx->VertexProgram._Current->Base.Parameters;
+
+ _mesa_load_state_parameters(ctx, paramList);
+
+ if (paramList->NumParameters > EVERGREEN_MAX_DX9_CONSTS)
+ return GL_FALSE;
+
+ EVERGREEN_STATECHANGE(context, vs);
+
+ evergreen->vs.num_consts = paramList->NumParameters;
+
+ unNumParamData = paramList->NumParameters;
+
+ for(ui=0; ui<unNumParamData; ui++) {
+ if(paramList->Parameters[ui].Type == PROGRAM_UNIFORM)
+ {
+ evergreen->vs.consts[ui][0].f32All = paramListOrginal->ParameterValues[ui][0];
+ evergreen->vs.consts[ui][1].f32All = paramListOrginal->ParameterValues[ui][1];
+ evergreen->vs.consts[ui][2].f32All = paramListOrginal->ParameterValues[ui][2];
+ evergreen->vs.consts[ui][3].f32All = paramListOrginal->ParameterValues[ui][3];
+ }
+ else
+ {
+ evergreen->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
+ evergreen->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
+ evergreen->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
+ evergreen->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+ }
+ }
+
+ radeonAllocDmaRegion(&context->radeon,
+ &context->vp_Constbo,
+ &context->vp_bo_offset,
+ 256,
+ 256);
+ r600EmitShaderConsts(ctx,
+ context->vp_Constbo,
+ context->vp_bo_offset,
+ (GLvoid *)&(evergreen->vs.consts[0][0]),
+ unNumParamData * 4 * 4);
+ } else
+ evergreen->vs.num_consts = 0;
+
+ COMPILED_SUB * pCompiledSub;
+ GLuint uj;
+ GLuint unConstOffset = evergreen->vs.num_consts;
+ for(ui=0; ui<vp->r700AsmCode.unNumPresub; ui++)
+ {
+ pCompiledSub = vp->r700AsmCode.presubs[ui].pCompiledSub;
+
+ evergreen->vs.num_consts += pCompiledSub->NumParameters;
+
+ for(uj=0; uj<pCompiledSub->NumParameters; uj++)
+ {
+ evergreen->vs.consts[uj + unConstOffset][0].f32All = pCompiledSub->ParameterValues[uj][0];
+ evergreen->vs.consts[uj + unConstOffset][1].f32All = pCompiledSub->ParameterValues[uj][1];
+ evergreen->vs.consts[uj + unConstOffset][2].f32All = pCompiledSub->ParameterValues[uj][2];
+ evergreen->vs.consts[uj + unConstOffset][3].f32All = pCompiledSub->ParameterValues[uj][3];
+ }
+ unConstOffset += pCompiledSub->NumParameters;
+ }
+} \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/evergreen_vertprog.h b/src/mesa/drivers/dri/r600/evergreen_vertprog.h
new file mode 100644
index 00000000000..58539021152
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/evergreen_vertprog.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008-2009 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * THE COPYRIGHT HOLDER(S) 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:
+ */
+
+
+#ifndef _EVERGREEN_VERTPROG_H_
+#define _EVERGREEN_VERTPROG_H_
+
+#include "main/glheader.h"
+#include "main/mtypes.h"
+
+#include "r700_shader.h"
+#include "r700_assembler.h"
+
+typedef struct evergreenArrayDesc //TEMP
+{
+ GLint size; //number of data element
+ GLenum type; //data element type
+ GLsizei stride;
+ GLenum format; //GL_RGBA or GL_BGRA
+} evergreenArrayDesc;
+
+struct evergreen_vertex_program
+{
+ struct gl_vertex_program *mesa_program; /* Must be first */
+
+ struct evergreen_vertex_program *next;
+
+ r700_AssemblerBase r700AsmCode;
+ R700_Shader r700Shader;
+
+ GLboolean translated;
+ GLboolean loaded;
+
+ void * shaderbo;
+
+ GLuint K0used;
+ void * constbo0;
+
+ evergreenArrayDesc aos_desc[VERT_ATTRIB_MAX];
+};
+
+struct evergreen_vertex_program_cont
+{
+ struct gl_vertex_program mesa_program;
+
+ struct evergreen_vertex_program *progs;
+};
+
+//Internal
+unsigned int evergreen_Map_Vertex_Output(r700_AssemblerBase *pAsm,
+ struct gl_vertex_program *mesa_vp,
+ unsigned int unStart);
+unsigned int evergreen_Map_Vertex_Input(r700_AssemblerBase *pAsm,
+ struct gl_vertex_program *mesa_vp,
+ unsigned int unStart);
+GLboolean evergreen_Process_Vertex_Program_Vfetch_Instructions(
+ struct evergreen_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp);
+GLboolean evergreen_Process_Vertex_Program_Vfetch_Instructions2(
+ GLcontext *ctx,
+ struct evergreen_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp);
+void evergreen_Map_Vertex_Program(GLcontext *ctx,
+ struct evergreen_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp);
+GLboolean evergreen_Find_Instruction_Dependencies_vp(struct evergreen_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp);
+
+struct evergreen_vertex_program* evergreenTranslateVertexShader(GLcontext *ctx,
+ struct gl_vertex_program *mesa_vp);
+
+/* Interface */
+extern void evergreenSelectVertexShader(GLcontext *ctx);
+extern void evergreenSetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count);
+
+extern GLboolean evergreenSetupVertexProgram(GLcontext * ctx);
+
+extern GLboolean evergreenSetupVPconstants(GLcontext * ctx);
+
+extern void * evergreenGetActiveVpShaderBo(GLcontext * ctx);
+
+extern void * evergreenGetActiveVpShaderConstBo(GLcontext * ctx);
+
+extern int evergreen_getTypeSize(GLenum type);
+
+#endif /* _EVERGREEN_VERTPROG_H_ */
diff --git a/src/mesa/drivers/dri/r600/r600_blit.c b/src/mesa/drivers/dri/r600/r600_blit.c
index 27acff9c166..ef47ae1c056 100644
--- a/src/mesa/drivers/dri/r600/r600_blit.c
+++ b/src/mesa/drivers/dri/r600/r600_blit.c
@@ -1454,7 +1454,7 @@ set_default_state(context_t *context)
SETbit(sq_dyn_gpr_cntl_ps_flush_req, VS_PC_LIMIT_ENABLE_bit);
}
- BEGIN_BATCH_NO_AUTOSTATE(117);
+ BEGIN_BATCH_NO_AUTOSTATE(120);
R600_OUT_BATCH_REGSEQ(SQ_CONFIG, 6);
R600_OUT_BATCH(sq_config);
R600_OUT_BATCH(sq_gpr_resource_mgmt_1);
@@ -1499,9 +1499,10 @@ set_default_state(context_t *context)
R600_OUT_BATCH_REGVAL(PA_SU_VTX_CNTL, (PIX_CENTER_bit) |
(X_ROUND_TO_EVEN << PA_SU_VTX_CNTL__ROUND_MODE_shift) |
(X_1_256TH << QUANT_MODE_shift));
+ R600_OUT_BATCH_REGVAL(PA_SC_AA_CONFIG, 0);
R600_OUT_BATCH_REGSEQ(VGT_MAX_VTX_INDX, 4);
- R600_OUT_BATCH(2048);
+ R600_OUT_BATCH(0xffffff);
R600_OUT_BATCH(0);
R600_OUT_BATCH(0);
R600_OUT_BATCH(0);
@@ -1614,7 +1615,7 @@ unsigned r600_blit(GLcontext *ctx,
/* Flush is needed to make sure that source buffer has correct data */
radeonFlush(ctx);
- rcommonEnsureCmdBufSpace(&context->radeon, 308, __FUNCTION__);
+ rcommonEnsureCmdBufSpace(&context->radeon, 311, __FUNCTION__);
/* load shaders */
load_shaders(context->radeon.glCtx);
@@ -1623,7 +1624,7 @@ unsigned r600_blit(GLcontext *ctx,
return GL_FALSE;
/* set clear state */
- /* 117 */
+ /* 120 */
set_default_state(context);
/* shaders */
diff --git a/src/mesa/drivers/dri/r600/r600_cmdbuf.c b/src/mesa/drivers/dri/r600/r600_cmdbuf.c
index 8013553f679..b3331fc8b88 100644
--- a/src/mesa/drivers/dri/r600/r600_cmdbuf.c
+++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.c
@@ -473,7 +473,14 @@ void r600InitCmdBuf(context_t *r600) /* from rcommonInitCmdBuf */
radeonContextPtr rmesa = &r600->radeon;
GLuint size;
- r600InitAtoms(r600);
+ if(r600->radeon.radeonScreen->chip_family >= CHIP_FAMILY_CEDAR)
+ {
+ evergreenInitAtoms(r600);
+ }
+ else
+ {
+ r600InitAtoms(r600);
+ }
/* Initialize command buffer */
size = 256 * driQueryOptioni(&rmesa->optionCache,
diff --git a/src/mesa/drivers/dri/r600/r600_cmdbuf.h b/src/mesa/drivers/dri/r600/r600_cmdbuf.h
index 78fccd0b601..801bb013f6e 100644
--- a/src/mesa/drivers/dri/r600/r600_cmdbuf.h
+++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.h
@@ -190,6 +190,46 @@ do { \
#define R600_OUT_BATCH_REGSEQ(reg, count) \
R600_OUT_BATCH_REGS((reg), (count))
+/* evergreen */
+#define EVERGREEN_OUT_BATCH_REGS(reg, num) \
+do { \
+ if ((reg) >= R600_SET_CONFIG_REG_OFFSET && (reg) < R600_SET_CONFIG_REG_END) { \
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, (num))); \
+ R600_OUT_BATCH(((reg) - R600_SET_CONFIG_REG_OFFSET) >> 2); \
+ } else if ((reg) >= R600_SET_CONTEXT_REG_OFFSET && (reg) < R600_SET_CONTEXT_REG_END) { \
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONTEXT_REG, (num))); \
+ R600_OUT_BATCH(((reg) - R600_SET_CONTEXT_REG_OFFSET) >> 2); \
+ } else if ((reg) >= EG_SET_RESOURCE_OFFSET && (reg) < EG_SET_RESOURCE_END) { \
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, (num))); \
+ R600_OUT_BATCH(((reg) - EG_SET_RESOURCE_OFFSET) >> 2); \
+ } else if ((reg) >= EG_SET_LOOP_CONST_OFFSET && (reg) < EG_SET_LOOP_CONST_END) { \
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_LOOP_CONST, (num))); \
+ R600_OUT_BATCH(((reg) - EG_SET_LOOP_CONST_OFFSET) >> 2); \
+ } else if ((reg) >= R600_SET_SAMPLER_OFFSET && (reg) < R600_SET_SAMPLER_END) { \
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, (num))); \
+ R600_OUT_BATCH(((reg) - R600_SET_SAMPLER_OFFSET) >> 2); \
+ } else if ((reg) >= R600_SET_CTL_CONST_OFFSET && (reg) < R600_SET_CTL_CONST_END) { \
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, (num))); \
+ R600_OUT_BATCH(((reg) - R600_SET_CTL_CONST_OFFSET) >> 2); \
+ } else if ((reg) >= EG_SET_BOOL_CONST_OFFSET && (reg) < EG_SET_BOOL_CONST_END) { \
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_BOOL_CONST, (num))); \
+ R600_OUT_BATCH(((reg) - EG_SET_BOOL_CONST_OFFSET) >> 2); \
+ } else { \
+ R600_OUT_BATCH(CP_PACKET0((reg), (num))); \
+ } \
+} while (0)
+
+/** Single register write to command buffer; requires 3 dwords for most things. */
+#define EVERGREEN_OUT_BATCH_REGVAL(reg, val) \
+ EVERGREEN_OUT_BATCH_REGS((reg), 1); \
+ R600_OUT_BATCH((val))
+
+/** Continuous register range write to command buffer; requires 1 dword,
+ * expects count dwords afterwards for register contents. */
+#define EVERGREEN_OUT_BATCH_REGSEQ(reg, count) \
+ EVERGREEN_OUT_BATCH_REGS((reg), (count))
+
+
extern void r600InitCmdBuf(context_t *r600);
#endif /* __R600_CMDBUF_H__ */
diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c
index 389b0412baa..bb959e7d2d9 100644
--- a/src/mesa/drivers/dri/r600/r600_context.c
+++ b/src/mesa/drivers/dri/r600/r600_context.c
@@ -66,6 +66,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r700_state.h"
#include "r700_ioctl.h"
+#include "evergreen_context.h"
+#include "evergreen_state.h"
+#include "evergreen_tex.h"
+#include "evergreen_ioctl.h"
+#include "evergreen_oglprog.h"
#include "utils.h"
@@ -247,6 +252,19 @@ static void r600_init_vtbl(radeonContextPtr radeon)
static void r600InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+
+ if( (context->radeon.radeonScreen->chip_family >= CHIP_FAMILY_CEDAR)
+ &&(context->radeon.radeonScreen->chip_family <= CHIP_FAMILY_HEMLOCK) )
+ {
+ r700->bShaderUseMemConstant = GL_TRUE;
+ }
+ else
+ {
+ r700->bShaderUseMemConstant = GL_FALSE;
+ }
+
ctx->Const.MaxTextureImageUnits = 16;
/* 8 per clause on r6xx, 16 on r7xx
* but I think mesa only supports 8 at the moment
@@ -381,18 +399,45 @@ GLboolean r600CreateContext(gl_api api,
r600ParseOptions(r600, screen);
r600->radeon.radeonScreen = screen;
- r600_init_vtbl(&r600->radeon);
+ if(screen->chip_family >= CHIP_FAMILY_CEDAR)
+ {
+ evergreen_init_vtbl(&r600->radeon);
+ }
+ else
+ {
+ r600_init_vtbl(&r600->radeon);
+ }
+
/* Init default driver functions then plug in our R600-specific functions
* (the texture functions are especially important)
*/
_mesa_init_driver_functions(&functions);
- r700InitStateFuncs(&r600->radeon, &functions);
- r600InitTextureFuncs(&r600->radeon, &functions);
- r700InitShaderFuncs(&functions);
+ if(screen->chip_family >= CHIP_FAMILY_CEDAR)
+ {
+ evergreenCreateChip(r600);
+ evergreenInitStateFuncs(&r600->radeon, &functions);
+ evergreenInitTextureFuncs(&r600->radeon, &functions);
+ evergreenInitShaderFuncs(&functions);
+ }
+ else
+ {
+ r700InitStateFuncs(&r600->radeon, &functions);
+ r600InitTextureFuncs(&r600->radeon, &functions);
+ r700InitShaderFuncs(&functions);
+ }
+
radeonInitQueryObjFunctions(&functions);
- r700InitIoctlFuncs(&functions);
+
+ if(screen->chip_family >= CHIP_FAMILY_CEDAR)
+ {
+ evergreenInitIoctlFuncs(&functions);
+ }
+ else
+ {
+ r700InitIoctlFuncs(&functions);
+ }
radeonInitBufferObjectFuncs(&functions);
if (!radeonInitContext(&r600->radeon, &functions,
@@ -435,16 +480,46 @@ GLboolean r600CreateContext(gl_api api,
radeon_init_debug();
- r700InitDraw(ctx);
+ if(screen->chip_family >= CHIP_FAMILY_CEDAR)
+ {
+ evergreenInitDraw(ctx);
+ }
+ else
+ {
+ r700InitDraw(ctx);
+ }
radeon_fbo_init(&r600->radeon);
radeonInitSpanFuncs( ctx );
r600InitCmdBuf(r600);
- r700InitState(r600->radeon.glCtx);
+
+ if(screen->chip_family >= CHIP_FAMILY_CEDAR)
+ {
+ evergreenInitState(r600->radeon.glCtx);
+ }
+ else
+ {
+ r700InitState(r600->radeon.glCtx);
+ }
r600InitGLExtensions(ctx);
return GL_TRUE;
}
+void r600DestroyContext(__DRIcontext *driContextPriv )
+{
+ void *pChip;
+ context_t *context = (context_t *) driContextPriv->driverPrivate;
+
+ assert(context);
+
+ pChip = context->pChip;
+
+ /* destroy context first, free pChip, in case there are things flush to asic. */
+ radeonDestroyContext(driContextPriv);
+
+ FREE(pChip);
+}
+
diff --git a/src/mesa/drivers/dri/r600/r600_context.h b/src/mesa/drivers/dri/r600/r600_context.h
index 063dd7c49a1..6a831966487 100644
--- a/src/mesa/drivers/dri/r600/r600_context.h
+++ b/src/mesa/drivers/dri/r600/r600_context.h
@@ -53,6 +53,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r700_oglprog.h"
#include "r700_vertprog.h"
+#include "evergreen_chip.h"
+
struct r600_context;
typedef struct r600_context context_t;
@@ -63,6 +65,10 @@ typedef struct r600_context context_t;
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
+#define FORCE_CF_TEX_BARRIER 1
+
+/* #define GENERATE_SHADER_FOR_2D 1 */
+
#define R600_FALLBACK_NONE 0
#define R600_FALLBACK_TCL 1
#define R600_FALLBACK_RAST 2
@@ -103,6 +109,24 @@ struct r600_hw_state {
struct radeon_state_atom tx_brdr_clr;
};
+struct evergreen_hw_state {
+ struct radeon_state_atom one_time_init;
+ struct radeon_state_atom init;
+ struct radeon_state_atom pa;
+ struct radeon_state_atom vgt;
+ struct radeon_state_atom tp;
+ struct radeon_state_atom sq;
+ struct radeon_state_atom vs;
+ struct radeon_state_atom spi;
+ struct radeon_state_atom sx;
+ struct radeon_state_atom tx;
+ struct radeon_state_atom db;
+ struct radeon_state_atom cb;
+ struct radeon_state_atom vtx;
+ struct radeon_state_atom cp;
+ struct radeon_state_atom timestamp;
+};
+
typedef struct StreamDesc
{
GLint size; //number of data element
@@ -141,6 +165,9 @@ struct r600_context {
struct r600_hw_state atoms;
+ struct evergreen_hw_state evergreen_atoms;
+ void * pChip;
+
struct r700_vertex_program *selected_vp;
/* Vertex buffers
@@ -150,16 +177,29 @@ struct r600_context {
struct r700_index_buffer ind_buf;
struct radeon_bo *blit_bo;
GLboolean blit_bo_loaded;
+
+ /* Shader const buffer */
+ struct radeon_bo * vp_Constbo;
+ int vp_bo_offset;
+ struct radeon_bo * fp_Constbo;
+ int fp_bo_offset;
};
+#define EVERGREEN_CONTEXT(ctx) ((context_t *)(ctx->DriverCtx))
+
#define R700_CONTEXT(ctx) ((context_t *)(ctx->DriverCtx))
#define GL_CONTEXT(context) ((GLcontext *)(context->radeon.glCtx))
+#define GET_EVERGREEN_CHIP(context) ((EVERGREEN_CHIP_CONTEXT*)(context->pChip))
+
extern GLboolean r600CreateContext(gl_api api,
const __GLcontextModes * glVisual,
__DRIcontext * driContextPriv,
void *sharedContextPrivate);
+extern void r600DestroyContext(__DRIcontext *driContextPriv );
+extern void evergreenCreateChip(context_t *context);
+
#define R700_CONTEXT_STATES(context) ((R700_CHIP_CONTEXT *)(&context->hw))
#define R600_NEWPRIM( rmesa ) \
@@ -175,6 +215,13 @@ do { \
r600->radeon.hw.is_dirty = GL_TRUE; \
} while(0)
+#define EVERGREEN_STATECHANGE(r600, ATOM) \
+do { \
+ R600_NEWPRIM(r600); \
+ r600->evergreen_atoms.ATOM.dirty = GL_TRUE; \
+ r600->radeon.hw.is_dirty = GL_TRUE; \
+} while(0)
+
extern GLboolean r700SyncSurf(context_t *context,
struct radeon_bo *pbo,
uint32_t read_domain,
@@ -187,6 +234,9 @@ extern void r700Start3D(context_t *context);
extern void r600InitAtoms(context_t *context);
extern void r700InitDraw(GLcontext *ctx);
+extern void evergreenInitAtoms(context_t *context);
+extern void evergreenInitDraw(GLcontext *ctx);
+
#define RADEON_D_CAPTURE 0
#define RADEON_D_PLAYBACK 1
#define RADEON_D_PLAYBACK_RAW 2
diff --git a/src/mesa/drivers/dri/r600/r600_emit.c b/src/mesa/drivers/dri/r600/r600_emit.c
index 1eb89a53058..a840106c144 100644
--- a/src/mesa/drivers/dri/r600/r600_emit.c
+++ b/src/mesa/drivers/dri/r600/r600_emit.c
@@ -49,6 +49,71 @@ void r600EmitCacheFlush(context_t *rmesa)
{
}
+GLboolean r600AllocShaderConsts(GLcontext * ctx,
+ void ** constbo,
+ int sizeinBYTE,
+ char * szShaderUsage)
+{
+ radeonContextPtr radeonctx = RADEON_CONTEXT(ctx);
+ struct radeon_bo * pbo;
+
+ if(sizeinBYTE < 64) /* SQ_ALU_CONST_BUFFER_SIZE need 64 bytes at least to be non 0 */
+ {
+ sizeinBYTE = 64;
+ }
+
+shader_again_alloc:
+ pbo = radeon_bo_open(radeonctx->radeonScreen->bom,
+ 0,
+ sizeinBYTE,
+ 256,
+ RADEON_GEM_DOMAIN_GTT,
+ 0);
+
+ radeon_print(RADEON_SHADER, RADEON_NORMAL, "%s %p size %d: %s\n", __func__, pbo, sizeinBYTE, szShaderUsage);
+
+ if (!pbo) {
+ radeon_print(RADEON_MEMORY | RADEON_CS, RADEON_IMPORTANT, "No memory for buffer object. Flushing command buffer.\n");
+ rcommonFlushCmdBuf(radeonctx, __FUNCTION__);
+ goto shader_again_alloc;
+ }
+
+ radeon_cs_space_add_persistent_bo(radeonctx->cmdbuf.cs,
+ pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+
+ if (radeon_cs_space_check_with_bo(radeonctx->cmdbuf.cs,
+ pbo,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
+ radeon_error("failure to revalidate BOs - badness\n");
+ return GL_FALSE;
+ }
+
+ *constbo = (void*)pbo;
+
+ return GL_TRUE;
+}
+GLboolean r600EmitShaderConsts(GLcontext * ctx,
+ void * constbo,
+ int bo_offset,
+ GLvoid * data,
+ int sizeinBYTE)
+{
+ struct radeon_bo * pbo = (struct radeon_bo *)constbo;
+ uint8_t *out;
+
+ radeon_bo_map(pbo, 1);
+
+ out = (uint8_t*)(pbo->ptr);
+ out = (uint8_t*)ADD_POINTERS(pbo->ptr, bo_offset);
+
+ memcpy(out, data, sizeinBYTE);
+
+ radeon_bo_unmap(pbo);
+
+ return GL_TRUE;
+}
+
GLboolean r600EmitShader(GLcontext * ctx,
void ** shaderbo,
GLvoid * data,
diff --git a/src/mesa/drivers/dri/r600/r600_emit.h b/src/mesa/drivers/dri/r600/r600_emit.h
index 661774d11ea..259561539fa 100644
--- a/src/mesa/drivers/dri/r600/r600_emit.h
+++ b/src/mesa/drivers/dri/r600/r600_emit.h
@@ -52,4 +52,14 @@ extern GLboolean r600EmitShader(GLcontext * ctx,
extern GLboolean r600DeleteShader(GLcontext * ctx,
void * shaderbo);
+extern GLboolean r600AllocShaderConsts(GLcontext * ctx,
+ void ** constbo,
+ int sizeinBYTE,
+ char * szShaderUsage);
+GLboolean r600EmitShaderConsts(GLcontext * ctx,
+ void * constbo,
+ int bo_offset,
+ GLvoid * data,
+ int sizeinBYTE);
+
#endif
diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c
index ba3690b70ed..fd928cfe5d2 100644
--- a/src/mesa/drivers/dri/r600/r600_texstate.c
+++ b/src/mesa/drivers/dri/r600/r600_texstate.c
@@ -50,6 +50,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r700_fragprog.h"
#include "r700_vertprog.h"
+#include "evergreen_tex.h"
+
void r600UpdateTextureState(GLcontext * ctx);
void r600UpdateTextureState(GLcontext * ctx)
@@ -878,6 +880,18 @@ GLboolean r600ValidateBuffers(GLcontext * ctx)
RADEON_GEM_DOMAIN_GTT, 0);
}
+ pbo = (struct radeon_bo *)r700GetActiveFpShaderConstBo(ctx);
+ if (pbo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+
+ pbo = (struct radeon_bo *)r700GetActiveVpShaderConstBo(ctx);
+ if (pbo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+
ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
if (ret)
return GL_FALSE;
@@ -897,6 +911,12 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
if (!tObj)
return;
+ if(rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_CEDAR)
+ {
+ evergreenSetTexOffset(pDRICtx, texname, offset, depth, pitch);
+ return;
+ }
+
t->image_override = GL_TRUE;
if (!offset)
@@ -989,6 +1009,12 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
radeon = pDRICtx->driverPrivate;
rmesa = pDRICtx->driverPrivate;
+ if(rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_CEDAR)
+ {
+ evergreenSetTexBuffer(pDRICtx, target, glx_texture_format, dPriv);
+ return;
+ }
+
rfb = dPriv->driverPrivate;
texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index 9c954cbf70c..45ff9c06249 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.c
+++ b/src/mesa/drivers/dri/r600/r700_assembler.c
@@ -38,6 +38,7 @@
#include "r600_context.h"
#include "r700_assembler.h"
+#include "evergreen_sq.h"
#define USE_CF_FOR_CONTINUE_BREAK 1
#define USE_CF_FOR_POP_AFTER 1
@@ -258,6 +259,18 @@ GLboolean is_reduction_opcode(PVSDWORD* dest)
return GL_FALSE;
}
+GLboolean EG_is_reduction_opcode(PVSDWORD* dest)
+{
+ if (dest->dst.op3 == 0)
+ {
+ if ( (dest->dst.opcode == EG_OP2_INST_DOT4 || dest->dst.opcode == EG_OP2_INST_DOT4_IEEE || dest->dst.opcode == EG_OP2_INST_CUBE) )
+ {
+ return GL_TRUE;
+ }
+ }
+ return GL_FALSE;
+}
+
GLuint GetSurfaceFormat(GLenum eType, GLuint nChannels, GLuint * pClient_size)
{
GLuint format = FMT_INVALID;
@@ -423,6 +436,60 @@ unsigned int r700GetNumOperands(GLuint opcode, GLuint nIsOp3)
return 3;
}
+unsigned int EG_GetNumOperands(GLuint opcode, GLuint nIsOp3)
+{
+ if(nIsOp3 > 0)
+ {
+ return 3;
+ }
+
+ switch (opcode)
+ {
+ case EG_OP2_INST_ADD:
+ case EG_OP2_INST_KILLE:
+ case EG_OP2_INST_KILLGT:
+ case EG_OP2_INST_KILLGE:
+ case EG_OP2_INST_KILLNE:
+ case EG_OP2_INST_MUL:
+ case EG_OP2_INST_MAX:
+ case EG_OP2_INST_MIN:
+ //case EG_OP2_INST_MAX_DX10:
+ //case EG_OP2_INST_MIN_DX10:
+ case EG_OP2_INST_SETE:
+ case EG_OP2_INST_SETNE:
+ case EG_OP2_INST_SETGT:
+ case EG_OP2_INST_SETGE:
+ case EG_OP2_INST_PRED_SETE:
+ case EG_OP2_INST_PRED_SETGT:
+ case EG_OP2_INST_PRED_SETGE:
+ case EG_OP2_INST_PRED_SETNE:
+ case EG_OP2_INST_DOT4:
+ case EG_OP2_INST_DOT4_IEEE:
+ case EG_OP2_INST_CUBE:
+ return 2;
+
+ case EG_OP2_INST_MOV:
+ //case SQ_OP2_INST_MOVA_FLOOR:
+ case EG_OP2_INST_FRACT:
+ case EG_OP2_INST_FLOOR:
+ case EG_OP2_INST_TRUNC:
+ case EG_OP2_INST_EXP_IEEE:
+ case EG_OP2_INST_LOG_CLAMPED:
+ case EG_OP2_INST_LOG_IEEE:
+ case EG_OP2_INST_RECIP_IEEE:
+ case EG_OP2_INST_RECIPSQRT_IEEE:
+ case EG_OP2_INST_FLT_TO_INT:
+ case EG_OP2_INST_SIN:
+ case EG_OP2_INST_COS:
+ return 1;
+
+ default: radeon_error(
+ "Need instruction operand number for %x.\n", opcode);
+ };
+
+ return 3;
+}
+
int Init_r700_AssemblerBase(SHADER_PIPE_TYPE spt, r700_AssemblerBase* pAsm, R700_Shader* pShader)
{
GLuint i;
@@ -718,21 +785,55 @@ GLboolean add_vfetch_instruction(r700_AssemblerBase* pAsm,
return GL_FALSE;
}
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.pop_count = 0x0;
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.count = 0x0;
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_VTX;
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.barrier = 0x1;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, EG_CF_INST_VC,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ }
+ else
+ {
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.pop_count = 0x0;
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.count = 0x0;
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_VTX;
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
LinkVertexInstruction(pAsm->cf_current_vtx_clause_ptr, vertex_instruction_ptr );
}
else
{
- pAsm->cf_current_vtx_clause_ptr->m_Word1.f.count++;
+ if(8 == pAsm->unAsic)
+ {
+ unsigned int count = GETbits(pAsm->cf_current_vtx_clause_ptr->m_Word1.val,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask) + 1;
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, count,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_vtx_clause_ptr->m_Word1.f.count++;
+ }
}
AddVTXInstruction(pAsm->pR700Shader, vertex_instruction_ptr);
@@ -767,20 +868,59 @@ GLboolean add_tex_instruction(r700_AssemblerBase* pAsm,
radeon_error("Could not allocate a new TEX CF instruction.\n");
return GL_FALSE;
}
-
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.pop_count = 0x0;
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_TEX;
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.barrier = 0x0; //0x1;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, EG_CF_INST_TC,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+#ifdef FORCE_CF_TEX_BARRIER
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+#else
+ SETfield(pAsm->cf_current_tex_clause_ptr->m_Word1.val, 0,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+#endif
+ }
+ else
+ {
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.pop_count = 0x0;
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_TEX;
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.barrier = 0x0; //0x1;
+ }
}
else
- {
- pAsm->cf_current_tex_clause_ptr->m_Word1.f.count++;
+ {
+ if(8 == pAsm->unAsic)
+ {
+ unsigned int count = GETbits(pAsm->cf_current_tex_clause_ptr->m_Word1.val,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask) + 1;
+ SETfield(pAsm->cf_current_vtx_clause_ptr->m_Word1.val, count,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_tex_clause_ptr->m_Word1.f.count++;
+ }
}
// If this clause constains any TEX instruction that is dependent on a previous instruction,
@@ -891,6 +1031,188 @@ GLboolean assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
return GL_TRUE;
}
+GLboolean EG_assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
+ GLuint destination_register,
+ GLenum type,
+ GLint size,
+ GLubyte element,
+ GLuint _signed,
+ GLboolean normalize,
+ GLenum format,
+ VTX_FETCH_METHOD * pFetchMethod)
+{
+ GLuint client_size_inbyte;
+ GLuint data_format;
+ GLuint mega_fetch_count;
+ GLuint is_mega_fetch_flag;
+
+ GLuint dst_sel_x, dst_sel_y, dst_sel_z, dst_sel_w;
+
+ R700VertexGenericFetch* vfetch_instruction_ptr;
+ R700VertexGenericFetch* assembled_vfetch_instruction_ptr
+ = pAsm->vfetch_instruction_ptr_array[element];
+
+ if (assembled_vfetch_instruction_ptr == NULL)
+ {
+ vfetch_instruction_ptr = (R700VertexGenericFetch*) CALLOC_STRUCT(R700VertexGenericFetch);
+ if (vfetch_instruction_ptr == NULL)
+ {
+ return GL_FALSE;
+ }
+ Init_R700VertexGenericFetch(vfetch_instruction_ptr);
+ }
+ else
+ {
+ vfetch_instruction_ptr = assembled_vfetch_instruction_ptr;
+ }
+
+ data_format = GetSurfaceFormat(type, size, &client_size_inbyte);
+
+ if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here
+ {
+ //TODO : mini fetch
+ mega_fetch_count = 0;
+ is_mega_fetch_flag = 0;
+ }
+ else
+ {
+ mega_fetch_count = MEGA_FETCH_BYTES - 1;
+ is_mega_fetch_flag = 0x1;
+ pFetchMethod->mega_fetch_remainder = MEGA_FETCH_BYTES - client_size_inbyte;
+ }
+
+ SETfield(vfetch_instruction_ptr->m_Word0.val, EG_VC_INST_FETCH,
+ EG_VTX_WORD0__VC_INST_shift,
+ EG_VTX_WORD0__VC_INST_mask);
+ SETfield(vfetch_instruction_ptr->m_Word0.val, EG_VTX_FETCH_VERTEX_DATA,
+ EG_VTX_WORD0__FETCH_TYPE_shift,
+ EG_VTX_WORD0__FETCH_TYPE_mask);
+ CLEARbit(vfetch_instruction_ptr->m_Word0.val,
+ EG_VTX_WORD0__FWQ_bit);
+ SETfield(vfetch_instruction_ptr->m_Word0.val, element,
+ EG_VTX_WORD0__BUFFER_ID_shift,
+ EG_VTX_WORD0__BUFFER_ID_mask);
+ SETfield(vfetch_instruction_ptr->m_Word0.val, 0x0,
+ EG_VTX_WORD0__SRC_GPR_shift,
+ EG_VTX_WORD0__SRC_GPR_mask);
+ SETfield(vfetch_instruction_ptr->m_Word0.val, SQ_ABSOLUTE,
+ EG_VTX_WORD0__SRC_REL_shift,
+ EG_VTX_WORD0__SRC_REL_bit);
+ SETfield(vfetch_instruction_ptr->m_Word0.val, SQ_SEL_X,
+ EG_VTX_WORD0__SRC_SEL_X_shift,
+ EG_VTX_WORD0__SRC_SEL_X_mask);
+ SETfield(vfetch_instruction_ptr->m_Word0.val, mega_fetch_count,
+ EG_VTX_WORD0__MFC_shift,
+ EG_VTX_WORD0__MFC_mask);
+
+ if(format == GL_BGRA)
+ {
+ dst_sel_x = (size < 1) ? SQ_SEL_0 : SQ_SEL_Z;
+ dst_sel_y = (size < 2) ? SQ_SEL_0 : SQ_SEL_Y;
+ dst_sel_z = (size < 3) ? SQ_SEL_0 : SQ_SEL_X;
+ dst_sel_w = (size < 4) ? SQ_SEL_1 : SQ_SEL_W;
+ }
+ else
+ {
+ dst_sel_x = (size < 1) ? SQ_SEL_0 : SQ_SEL_X;
+ dst_sel_y = (size < 2) ? SQ_SEL_0 : SQ_SEL_Y;
+ dst_sel_z = (size < 3) ? SQ_SEL_0 : SQ_SEL_Z;
+ dst_sel_w = (size < 4) ? SQ_SEL_1 : SQ_SEL_W;
+
+ }
+ SETfield(vfetch_instruction_ptr->m_Word1.val, dst_sel_x,
+ EG_VTX_WORD1__DST_SEL_X_shift,
+ EG_VTX_WORD1__DST_SEL_X_mask);
+ SETfield(vfetch_instruction_ptr->m_Word1.val, dst_sel_y,
+ EG_VTX_WORD1__DST_SEL_Y_shift,
+ EG_VTX_WORD1__DST_SEL_Y_mask);
+ SETfield(vfetch_instruction_ptr->m_Word1.val, dst_sel_z,
+ EG_VTX_WORD1__DST_SEL_Z_shift,
+ EG_VTX_WORD1__DST_SEL_Z_mask);
+ SETfield(vfetch_instruction_ptr->m_Word1.val, dst_sel_w,
+ EG_VTX_WORD1__DST_SEL_W_shift,
+ EG_VTX_WORD1__DST_SEL_W_mask);
+
+ SETfield(vfetch_instruction_ptr->m_Word1.val, 0, /* use format here, in r6/r7, format used set in const, need to use same */
+ EG_VTX_WORD1__UCF_shift,
+ EG_VTX_WORD1__UCF_bit);
+ SETfield(vfetch_instruction_ptr->m_Word1.val, data_format,
+ EG_VTX_WORD1__DATA_FORMAT_shift,
+ EG_VTX_WORD1__DATA_FORMAT_mask);
+#ifdef TEST_VFETCH
+ SETfield(vfetch_instruction_ptr->m_Word1.val, SQ_FORMAT_COMP_SIGNED,
+ EG_VTX_WORD1__FCA_shift,
+ EG_VTX_WORD1__FCA_bit);
+#else
+ if(1 == _signed)
+ {
+ SETfield(vfetch_instruction_ptr->m_Word1.val, SQ_FORMAT_COMP_SIGNED,
+ EG_VTX_WORD1__FCA_shift,
+ EG_VTX_WORD1__FCA_bit);
+ }
+ else
+ {
+ SETfield(vfetch_instruction_ptr->m_Word1.val, SQ_FORMAT_COMP_UNSIGNED,
+ EG_VTX_WORD1__FCA_shift,
+ EG_VTX_WORD1__FCA_bit);
+ }
+#endif /* TEST_VFETCH */
+
+ if(GL_TRUE == normalize)
+ {
+ SETfield(vfetch_instruction_ptr->m_Word1.val, SQ_NUM_FORMAT_NORM,
+ EG_VTX_WORD1__NFA_shift,
+ EG_VTX_WORD1__NFA_mask);
+ }
+ else
+ {
+ SETfield(vfetch_instruction_ptr->m_Word1.val, SQ_NUM_FORMAT_SCALED,
+ EG_VTX_WORD1__NFA_shift,
+ EG_VTX_WORD1__NFA_mask);
+ }
+
+ /* Destination register */
+ SETfield(vfetch_instruction_ptr->m_Word1.val, destination_register,
+ EG_VTX_WORD1_GPR__DST_GPR_shift,
+ EG_VTX_WORD1_GPR__DST_GPR_mask);
+ SETfield(vfetch_instruction_ptr->m_Word1.val, SQ_ABSOLUTE,
+ EG_VTX_WORD1_GPR__DST_REL_shift,
+ EG_VTX_WORD1_GPR__DST_REL_bit);
+
+
+ SETfield(vfetch_instruction_ptr->m_Word2.val, 0,
+ EG_VTX_WORD2__OFFSET_shift,
+ EG_VTX_WORD2__OFFSET_mask);
+ SETfield(vfetch_instruction_ptr->m_Word2.val, SQ_ENDIAN_NONE,
+ EG_VTX_WORD2__ENDIAN_SWAP_shift,
+ EG_VTX_WORD2__ENDIAN_SWAP_mask);
+ SETfield(vfetch_instruction_ptr->m_Word2.val, 0,
+ EG_VTX_WORD2__CBNS_shift,
+ EG_VTX_WORD2__CBNS_bit);
+ SETfield(vfetch_instruction_ptr->m_Word2.val, is_mega_fetch_flag,
+ EG_VTX_WORD2__MEGA_FETCH_shift,
+ EG_VTX_WORD2__MEGA_FETCH_mask);
+
+ if (assembled_vfetch_instruction_ptr == NULL)
+ {
+ if ( GL_FALSE == add_vfetch_instruction(pAsm, (R700VertexInstruction *)vfetch_instruction_ptr) )
+ {
+ return GL_FALSE;
+ }
+
+ if (pAsm->vfetch_instruction_ptr_array[element] != NULL)
+ {
+ return GL_FALSE;
+ }
+ else
+ {
+ pAsm->vfetch_instruction_ptr_array[element] = vfetch_instruction_ptr;
+ }
+ }
+
+ return GL_TRUE;
+}
+
GLboolean assemble_vfetch_instruction2(r700_AssemblerBase* pAsm,
GLuint destination_register,
GLenum type,
@@ -1357,7 +1679,7 @@ GLboolean assemble_src(r700_AssemblerBase *pAsm,
break;
case PROGRAM_INPUT:
setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE);
- pAsm->S[fld].src.rtype = SRC_REG_INPUT;
+ pAsm->S[fld].src.rtype = SRC_REG_GPR;
switch (pAsm->currentShaderType)
{
case SPT_FP:
@@ -1368,6 +1690,19 @@ GLboolean assemble_src(r700_AssemblerBase *pAsm,
break;
}
break;
+ case PROGRAM_OUTPUT:
+ setaddrmode_PVSSRC(&(pAsm->S[fld].src), ADDR_ABSOLUTE);
+ pAsm->S[fld].src.rtype = SRC_REG_GPR;
+ switch (pAsm->currentShaderType)
+ {
+ case SPT_FP:
+ pAsm->S[fld].src.reg = pAsm->uiFP_OutputMap[pILInst->SrcReg[src].Index];
+ break;
+ case SPT_VP:
+ pAsm->S[fld].src.reg = pAsm->ucVP_OutputMap[pILInst->SrcReg[src].Index];
+ break;
+ }
+ break;
default:
radeon_error("Invalid source argument type : %d \n", pILInst->SrcReg[src].File);
return GL_FALSE;
@@ -1521,7 +1856,7 @@ GLboolean tex_src(r700_AssemblerBase *pAsm)
bValidTexCoord = GL_TRUE;
pAsm->S[0].src.reg =
pAsm->ucVP_AttributeMap[pILInst->SrcReg[0].Index];
- pAsm->S[0].src.rtype = SRC_REG_INPUT;
+ pAsm->S[0].src.rtype = SRC_REG_GPR;
break;
}
}
@@ -1544,7 +1879,7 @@ GLboolean tex_src(r700_AssemblerBase *pAsm)
bValidTexCoord = GL_TRUE;
pAsm->S[0].src.reg =
pAsm->uiFP_AttributeMap[pILInst->SrcReg[0].Index];
- pAsm->S[0].src.rtype = SRC_REG_INPUT;
+ pAsm->S[0].src.rtype = SRC_REG_GPR;
break;
case FRAG_ATTRIB_FACE:
fprintf(stderr, "FRAG_ATTRIB_FACE unsupported\n");
@@ -1560,7 +1895,7 @@ GLboolean tex_src(r700_AssemblerBase *pAsm)
bValidTexCoord = GL_TRUE;
pAsm->S[0].src.reg =
pAsm->uiFP_AttributeMap[pILInst->SrcReg[0].Index];
- pAsm->S[0].src.rtype = SRC_REG_INPUT;
+ pAsm->S[0].src.rtype = SRC_REG_GPR;
}
}
@@ -1606,19 +1941,68 @@ GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm, GLboolean normalize
texture_coordinate_source = &(pAsm->S[0].src);
texture_unit_source = &(pAsm->S[1].src);
- tex_instruction_ptr->m_Word0.f.tex_inst = pAsm->D.dst.opcode;
- tex_instruction_ptr->m_Word0.f.bc_frac_mode = 0x0;
- tex_instruction_ptr->m_Word0.f.fetch_whole_quad = 0x0;
- tex_instruction_ptr->m_Word0.f.alt_const = 0;
-
- if(SPT_VP == pAsm->currentShaderType)
+ if(8 == pAsm->unAsic) /* evergreen */
{
- tex_instruction_ptr->m_Word0.f.resource_id = texture_unit_source->reg + VERT_ATTRIB_MAX;
- pAsm->unVetTexBits |= 1 << texture_unit_source->reg;
+
+ SETfield(tex_instruction_ptr->m_Word0.val, pAsm->D.dst.opcode,
+ EG_TEX_WORD0__TEX_INST_shift,
+ EG_TEX_WORD0__TEX_INST_mask);
+
+ if( (SQ_TEX_INST_GET_GRADIENTS_H == pAsm->D.dst.opcode)
+ ||(SQ_TEX_INST_GET_GRADIENTS_V == pAsm->D.dst.opcode) )
+ {
+ /* Use fine texel derivative calculation rather than use quad derivative */
+ SETfield(tex_instruction_ptr->m_Word0.val, 1,
+ EG_TEX_WORD0__INST_MOD_shift,
+ EG_TEX_WORD0__INST_MOD_mask);
+ }
+ else
+ {
+ SETfield(tex_instruction_ptr->m_Word0.val, 0,
+ EG_TEX_WORD0__INST_MOD_shift,
+ EG_TEX_WORD0__INST_MOD_mask);
+ }
+
+ CLEARbit(tex_instruction_ptr->m_Word0.val, EG_TEX_WORD0__FWQ_bit);
+
+ if(SPT_VP == pAsm->currentShaderType)
+ {
+ SETfield(tex_instruction_ptr->m_Word0.val, (texture_unit_source->reg + VERT_ATTRIB_MAX),
+ EG_TEX_WORD0__RESOURCE_ID_shift,
+ EG_TEX_WORD0__RESOURCE_ID_mask);
+ pAsm->unVetTexBits |= 1 << texture_unit_source->reg;
+ }
+ else
+ {
+ SETfield(tex_instruction_ptr->m_Word0.val, texture_unit_source->reg,
+ EG_TEX_WORD0__RESOURCE_ID_shift,
+ EG_TEX_WORD0__RESOURCE_ID_mask);
+ }
+
+ CLEARbit(tex_instruction_ptr->m_Word0.val, EG_TEX_WORD0__ALT_CONST_bit);
+ SETfield(tex_instruction_ptr->m_Word0.val, 0,
+ EG_TEX_WORD0__RIM_shift,
+ EG_TEX_WORD0__RIM_mask);
+ SETfield(tex_instruction_ptr->m_Word0.val, 0,
+ EG_TEX_WORD0__SIM_shift,
+ EG_TEX_WORD0__SIM_mask);
}
else
{
- tex_instruction_ptr->m_Word0.f.resource_id = texture_unit_source->reg;
+ tex_instruction_ptr->m_Word0.f.tex_inst = pAsm->D.dst.opcode;
+ tex_instruction_ptr->m_Word0.f.bc_frac_mode = 0x0;
+ tex_instruction_ptr->m_Word0.f.fetch_whole_quad = 0x0;
+ tex_instruction_ptr->m_Word0.f.alt_const = 0;
+
+ if(SPT_VP == pAsm->currentShaderType)
+ {
+ tex_instruction_ptr->m_Word0.f.resource_id = texture_unit_source->reg + VERT_ATTRIB_MAX;
+ pAsm->unVetTexBits |= 1 << texture_unit_source->reg;
+ }
+ else
+ {
+ tex_instruction_ptr->m_Word0.f.resource_id = texture_unit_source->reg;
+ }
}
tex_instruction_ptr->m_Word1.f.lod_bias = 0x0;
@@ -1644,8 +2028,20 @@ GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm, GLboolean normalize
if ( (pAsm->D.dst.rtype == DST_REG_TEMPORARY) ||
(pAsm->D.dst.rtype == DST_REG_OUT) )
{
- tex_instruction_ptr->m_Word0.f.src_gpr = texture_coordinate_source->reg;
- tex_instruction_ptr->m_Word0.f.src_rel = SQ_ABSOLUTE;
+ if(8 == pAsm->unAsic) /* evergreen */
+ {
+ SETfield(tex_instruction_ptr->m_Word0.val, texture_coordinate_source->reg,
+ EG_TEX_WORD0__SRC_GPR_shift,
+ EG_TEX_WORD0__SRC_GPR_mask);
+ SETfield(tex_instruction_ptr->m_Word0.val, SQ_ABSOLUTE,
+ EG_TEX_WORD0__SRC_REL_shift,
+ EG_TEX_WORD0__SRC_REL_bit);
+ }
+ else
+ {
+ tex_instruction_ptr->m_Word0.f.src_gpr = texture_coordinate_source->reg;
+ tex_instruction_ptr->m_Word0.f.src_rel = SQ_ABSOLUTE;
+ }
tex_instruction_ptr->m_Word1.f.dst_gpr = pAsm->D.dst.reg;
tex_instruction_ptr->m_Word1.f.dst_rel = SQ_ABSOLUTE;
@@ -1696,7 +2092,8 @@ void initialize(r700_AssemblerBase *pAsm)
GLboolean assemble_alu_src(R700ALUInstruction* alu_instruction_ptr,
int source_index,
PVSSRC* pSource,
- BITS scalar_channel_index)
+ BITS scalar_channel_index,
+ r700_AssemblerBase *pAsm)
{
BITS src_sel;
BITS src_rel;
@@ -1745,14 +2142,23 @@ GLboolean assemble_alu_src(R700ALUInstruction* alu_instruction_ptr,
else
{
if ( (pSource->rtype == SRC_REG_TEMPORARY) ||
- (pSource->rtype == SRC_REG_INPUT)
+ (pSource->rtype == SRC_REG_GPR)
)
{
src_sel = pSource->reg;
}
else if (pSource->rtype == SRC_REG_CONSTANT)
{
- src_sel = pSource->reg + CFILE_REGISTER_OFFSET;
+ /* TODO : 4 const buffers */
+ if(GL_TRUE == pAsm->bUseMemConstant)
+ {
+ src_sel = pSource->reg + SQ_ALU_SRC_KCACHE0_BASE;
+ pAsm->kcacheUsed = SQ_ALU_SRC_KCACHE0_BASE;
+ }
+ else
+ {
+ src_sel = pSource->reg + CFILE_REGISTER_OFFSET;
+ }
}
else if (pSource->rtype == SRC_REC_LITERAL)
{
@@ -1902,6 +2308,17 @@ GLboolean add_alu_instruction(r700_AssemblerBase* pAsm,
pAsm->cf_current_alu_clause_ptr->m_Word1.f.count += (GetInstructionSize(alu_instruction_ptr->m_ShaderInstType) / 2);
}
+ /* TODO : handle 4 bufs */
+ if( (pAsm->kcacheUsed > 0) && (GL_TRUE == pAsm->bUseMemConstant) )
+ {
+ pAsm->cf_current_alu_clause_ptr->m_Word0.f.kcache_bank0 = 0x0;
+ pAsm->cf_current_alu_clause_ptr->m_Word0.f.kcache_bank1 = 0x0;
+ pAsm->cf_current_alu_clause_ptr->m_Word0.f.kcache_mode0 = SQ_CF_KCACHE_LOCK_2;
+ pAsm->cf_current_alu_clause_ptr->m_Word1.f.kcache_mode1 = SQ_CF_KCACHE_NOP;
+ pAsm->cf_current_alu_clause_ptr->m_Word1.f.kcache_addr0 = 0x0;
+ pAsm->cf_current_alu_clause_ptr->m_Word1.f.kcache_addr1 = 0x0;
+ }
+
// If this clause constains any instruction that is forward dependent on a TEX instruction,
// set the whole_quad_mode for this clause
if ( pAsm->pInstDeps[pAsm->uiCurInst].nDstDep > (-1) )
@@ -1925,6 +2342,80 @@ GLboolean add_alu_instruction(r700_AssemblerBase* pAsm,
return GL_TRUE;
}
+GLboolean EG_add_ps_interp(r700_AssemblerBase* pAsm)
+{
+ R700ALUInstruction * alu_instruction_ptr = NULL;
+
+ int ui;
+ unsigned int uj;
+ unsigned int unWord0Temp = 0x380C00;
+ unsigned int unWord1Temp = 0x146B10; //SQ_SEL_X
+
+ if(pAsm->uIIns > 0)
+ {
+ for(ui=(pAsm->uIIns-1); ui>=0; ui--)
+ {
+ for(uj=0; uj<8; uj++)
+ {
+ alu_instruction_ptr = (R700ALUInstruction*) CALLOC_STRUCT(R700ALUInstruction);
+ Init_R700ALUInstruction(alu_instruction_ptr);
+ alu_instruction_ptr->m_Word0.val = unWord0Temp;
+ alu_instruction_ptr->m_Word1.val = unWord1Temp;
+
+ if(uj < 4)
+ {
+ SETfield(alu_instruction_ptr->m_Word1.val, EG_OP2_INST_INTERP_ZW,
+ EG_ALU_WORD1_OP2__ALU_INST_shift, EG_ALU_WORD1_OP2__ALU_INST_mask);
+ }
+ else
+ {
+ SETfield(alu_instruction_ptr->m_Word1.val, EG_OP2_INST_INTERP_XY,
+ EG_ALU_WORD1_OP2__ALU_INST_shift, EG_ALU_WORD1_OP2__ALU_INST_mask);
+ }
+ if( (uj > 1) && (uj < 6) )
+ {
+ SETfield(alu_instruction_ptr->m_Word1.val, 1,
+ EG_ALU_WORD1_OP2__WRITE_MASK_shift, EG_ALU_WORD1_OP2__WRITE_MASK_bit);
+ }
+ else
+ {
+ SETfield(alu_instruction_ptr->m_Word1.val, 0,
+ EG_ALU_WORD1_OP2__WRITE_MASK_shift, EG_ALU_WORD1_OP2__WRITE_MASK_bit);
+ }
+ if( (uj > 1) && (uj < 6) )
+ {
+ SETfield(alu_instruction_ptr->m_Word1.val, ui,
+ EG_ALU_WORD1__DST_GPR_shift, EG_ALU_WORD1__DST_GPR_mask);
+ }
+ else
+ {
+ SETfield(alu_instruction_ptr->m_Word1.val, 111,
+ EG_ALU_WORD1__DST_GPR_shift, EG_ALU_WORD1__DST_GPR_mask);
+ }
+
+ SETfield(alu_instruction_ptr->m_Word1.val, (uj % 4),
+ EG_ALU_WORD1__DST_CHAN_shift, EG_ALU_WORD1__DST_CHAN_mask);
+ SETfield(alu_instruction_ptr->m_Word0.val, (1 - (uj % 2)),
+ EG_ALU_WORD0__SRC0_CHAN_shift, EG_ALU_WORD0__SRC0_CHAN_mask);
+ SETfield(alu_instruction_ptr->m_Word0.val, (EG_ALU_SRC_PARAM_BASE + ui),
+ EG_ALU_WORD0__SRC1_SEL_shift, EG_ALU_WORD0__SRC1_SEL_mask);
+ if(3 == (uj % 4))
+ {
+ SETfield(alu_instruction_ptr->m_Word0.val, 1,
+ EG_ALU_WORD0__LAST_shift, EG_ALU_WORD0__LAST_bit);
+ }
+
+ if(GL_FALSE == add_alu_instruction(pAsm, alu_instruction_ptr, 4) )
+ {
+ return GL_FALSE;
+ }
+ }
+ }
+ }
+
+ return GL_TRUE;
+}
+
void get_src_properties(R700ALUInstruction* alu_instruction_ptr,
int source_index,
BITS* psrc_sel,
@@ -2175,8 +2666,16 @@ GLboolean check_scalar(r700_AssemblerBase* pAsm,
BITS src_neg [3] = {0,0,0};
GLuint swizzle_key;
+ GLuint number_of_operands;
- GLuint number_of_operands = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
+ if(8 == pAsm->unAsic)
+ {
+ number_of_operands = EG_GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
+ }
+ else
+ {
+ number_of_operands = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
+ }
for (src=0; src<number_of_operands; src++)
{
@@ -2264,8 +2763,16 @@ GLboolean check_vector(r700_AssemblerBase* pAsm,
BITS src_neg [3] = {0,0,0};
GLuint swizzle_key;
+ GLuint number_of_operands;
- GLuint number_of_operands = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
+ if(8 == pAsm->unAsic)
+ {
+ number_of_operands = EG_GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
+ }
+ else
+ {
+ number_of_operands = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
+ }
for (src=0; src<number_of_operands; src++)
{
@@ -2345,12 +2852,23 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
PVSSRC * pcurrent_source;
int current_source_index;
GLuint contiguous_slots_needed;
+ GLuint uNumSrc;
+ GLboolean bSplitInst;
+
+ if(8 == pAsm->unAsic)
+ {
+ uNumSrc = EG_GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
+ }
+ else
+ {
+ uNumSrc = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
+ }
- GLuint uNumSrc = r700GetNumOperands(pAsm->D.dst.opcode, pAsm->D.dst.op3);
//GLuint channel_swizzle, j;
//GLuint chan_counter[4] = {0, 0, 0, 0};
//PVSSRC * pSource[3];
- GLboolean bSplitInst = GL_FALSE;
+ bSplitInst = GL_FALSE;
+ pAsm->kcacheUsed = 0;
if (1 == pAsm->D.dst.math)
{
@@ -2384,7 +2902,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
default: channel_swizzle = SQ_SEL_MASK; break;
}
if ( ((pSource[j]->rtype == SRC_REG_TEMPORARY) ||
- (pSource[j]->rtype == SRC_REG_INPUT))
+ (pSource[j]->rtype == SRC_REG_GPR))
&& (channel_swizzle <= SQ_SEL_W) )
{
chan_counter[channel_swizzle]++;
@@ -2449,7 +2967,8 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
if (GL_FALSE == assemble_alu_src(alu_instruction_ptr,
current_source_index,
pcurrent_source,
- scalar_channel_index) )
+ scalar_channel_index,
+ pAsm) )
{
return GL_FALSE;
}
@@ -2463,7 +2982,8 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
if (GL_FALSE == assemble_alu_src(alu_instruction_ptr,
current_source_index,
pcurrent_source,
- scalar_channel_index) )
+ scalar_channel_index,
+ pAsm) )
{
return GL_FALSE;
}
@@ -2546,7 +3066,8 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
if ( GL_FALSE == assemble_alu_src(alu_instruction_ptr,
current_source_index,
pcurrent_source,
- scalar_channel_index) )
+ scalar_channel_index,
+ pAsm) )
{
return GL_FALSE;
}
@@ -2987,7 +3508,14 @@ GLboolean assemble_DOT(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->D.dst.opcode = SQ_OP2_INST_DOT4;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_DOT4;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_DOT4;
+ }
if( GL_FALSE == assemble_dst(pAsm) )
{
@@ -3004,7 +3532,14 @@ GLboolean assemble_DOT(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- if(OPCODE_DP3 == pAsm->pILInst[pAsm->uiCurInst].Opcode)
+ if(OPCODE_DP2 == pAsm->pILInst[pAsm->uiCurInst].Opcode)
+ {
+ zerocomp_PVSSRC(&(pAsm->S[0].src),2);
+ zerocomp_PVSSRC(&(pAsm->S[0].src),3);
+ zerocomp_PVSSRC(&(pAsm->S[1].src),2);
+ zerocomp_PVSSRC(&(pAsm->S[1].src),3);
+ }
+ else if(OPCODE_DP3 == pAsm->pILInst[pAsm->uiCurInst].Opcode)
{
zerocomp_PVSSRC(&(pAsm->S[0].src), 3);
zerocomp_PVSSRC(&(pAsm->S[1].src), 3);
@@ -3062,6 +3597,11 @@ GLboolean assemble_DST(r700_AssemblerBase *pAsm)
GLboolean assemble_EX2(r700_AssemblerBase *pAsm)
{
+ if(8 == pAsm->unAsic)
+ {
+ return assemble_math_function(pAsm, EG_OP2_INST_EXP_IEEE);
+ }
+
return assemble_math_function(pAsm, SQ_OP2_INST_EXP_IEEE);
}
@@ -3094,7 +3634,14 @@ GLboolean assemble_EXP(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_EXP_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ }
pAsm->D.dst.math = 1;
if( GL_FALSE == assemble_dst(pAsm) )
@@ -3143,7 +3690,14 @@ GLboolean assemble_EXP(r700_AssemblerBase *pAsm)
// EX2 dst.z, a.x
if ((pAsm->pILInst->DstReg.WriteMask >> 2) & 0x1) {
- pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_EXP_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ }
pAsm->D.dst.math = 1;
if( GL_FALSE == assemble_dst(pAsm) )
@@ -3218,6 +3772,11 @@ GLboolean assemble_FLR(r700_AssemblerBase *pAsm)
GLboolean assemble_FLR_INT(r700_AssemblerBase *pAsm)
{
+ if(8 == pAsm->unAsic)
+ {
+ return assemble_math_function(pAsm, EG_OP2_INST_FLT_TO_INT);
+ }
+
return assemble_math_function(pAsm, SQ_OP2_INST_FLT_TO_INT);
}
@@ -3300,6 +3859,11 @@ GLboolean assemble_KIL(r700_AssemblerBase *pAsm, GLuint opcode)
GLboolean assemble_LG2(r700_AssemblerBase *pAsm)
{
+ if(8 == pAsm->unAsic)
+ {
+ return assemble_math_function(pAsm, EG_OP2_INST_LOG_IEEE);
+ }
+
return assemble_math_function(pAsm, SQ_OP2_INST_LOG_IEEE);
}
@@ -3339,7 +3903,14 @@ GLboolean assemble_LRP(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP3_INST_MULADD;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ }
pAsm->D.dst.op3 = 1;
pAsm->D.dst.rtype = DST_REG_TEMPORARY;
@@ -3437,7 +4008,14 @@ GLboolean assemble_LOG(r700_AssemblerBase *pAsm)
// LG2 tmp2.x, tmp1.x
// FLOOR tmp3.x, tmp2.x
- pAsm->D.dst.opcode = SQ_OP2_INST_LOG_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_LOG_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_LOG_IEEE;
+ }
pAsm->D.dst.math = 1;
setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
@@ -3528,7 +4106,14 @@ GLboolean assemble_LOG(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_EXP_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ }
pAsm->D.dst.math = 1;
if( GL_FALSE == assemble_dst(pAsm) )
@@ -3610,7 +4195,14 @@ GLboolean assemble_MAD(struct r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP3_INST_MULADD;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ }
pAsm->D.dst.op3 = 1;
tmp = (-1);
@@ -3778,7 +4370,14 @@ GLboolean assemble_LIT(r700_AssemblerBase *pAsm)
swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_Y, SQ_SEL_Y, SQ_SEL_Y, SQ_SEL_Y);
/* dst.z = log(src.y) */
- pAsm->D.dst.opcode = SQ_OP2_INST_LOG_CLAMPED;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_LOG_CLAMPED;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_LOG_CLAMPED;
+ }
pAsm->D.dst.math = 1;
pAsm->D.dst.rtype = dstType;
pAsm->D.dst.reg = dstReg;
@@ -3809,7 +4408,14 @@ GLboolean assemble_LIT(r700_AssemblerBase *pAsm)
swizzleagain_PVSSRC(&(pAsm->S[2].src), SQ_SEL_X, SQ_SEL_X, SQ_SEL_X, SQ_SEL_X);
/* tmp.x = amd MUL_LIT(src.w, dst.z, src.x ) */
- pAsm->D.dst.opcode = SQ_OP3_INST_MUL_LIT;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP3_INST_MUL_LIT;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP3_INST_MUL_LIT;
+ }
pAsm->D.dst.math = 1;
pAsm->D.dst.op3 = 1;
pAsm->D.dst.rtype = DST_REG_TEMPORARY;
@@ -3842,7 +4448,14 @@ GLboolean assemble_LIT(r700_AssemblerBase *pAsm)
}
/* dst.z = exp(tmp.x) */
- pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_EXP_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ }
pAsm->D.dst.math = 1;
pAsm->D.dst.rtype = dstType;
pAsm->D.dst.reg = dstReg;
@@ -3997,7 +4610,14 @@ GLboolean assemble_POW(r700_AssemblerBase *pAsm)
tmp = gethelpr(pAsm);
// LG2 tmp.x, a.swizzle
- pAsm->D.dst.opcode = SQ_OP2_INST_LOG_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_LOG_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_LOG_IEEE;
+ }
pAsm->D.dst.math = 1;
setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
@@ -4041,7 +4661,14 @@ GLboolean assemble_POW(r700_AssemblerBase *pAsm)
// EX2 dst.mask, tmp.x
// EX2 tmp.x, tmp.x
- pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_EXP_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_EXP_IEEE;
+ }
pAsm->D.dst.math = 1;
setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
@@ -4085,11 +4712,21 @@ GLboolean assemble_POW(r700_AssemblerBase *pAsm)
GLboolean assemble_RCP(r700_AssemblerBase *pAsm)
{
+ if(8 == pAsm->unAsic)
+ {
+ return assemble_math_function(pAsm, EG_OP2_INST_RECIP_IEEE);
+ }
+
return assemble_math_function(pAsm, SQ_OP2_INST_RECIP_IEEE);
}
GLboolean assemble_RSQ(r700_AssemblerBase *pAsm)
{
+ if(8 == pAsm->unAsic)
+ {
+ return assemble_math_function(pAsm, EG_OP2_INST_RECIPSQRT_IEEE);
+ }
+
return assemble_math_function(pAsm, SQ_OP2_INST_RECIPSQRT_IEEE);
}
@@ -4175,7 +4812,14 @@ GLboolean assemble_SCS(r700_AssemblerBase *pAsm)
}
// COS dst.x, a.x
- pAsm->D.dst.opcode = SQ_OP2_INST_COS;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_COS;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_COS;
+ }
pAsm->D.dst.math = 1;
assemble_dst(pAsm);
@@ -4194,7 +4838,14 @@ GLboolean assemble_SCS(r700_AssemblerBase *pAsm)
}
// SIN dst.y, a.x
- pAsm->D.dst.opcode = SQ_OP2_INST_SIN;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_SIN;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_SIN;
+ }
pAsm->D.dst.math = 1;
assemble_dst(pAsm);
@@ -4349,6 +5000,65 @@ GLboolean assemble_SLT(r700_AssemblerBase *pAsm)
return GL_TRUE;
}
+GLboolean assemble_SSG(r700_AssemblerBase *pAsm)
+{
+ checkop1(pAsm);
+
+ GLuint tmp = gethelpr(pAsm);
+ /* tmp = (src > 0 ? 1 : src) */
+ pAsm->D.dst.opcode = SQ_OP3_INST_CNDGT;
+ pAsm->D.dst.op3 = 1;
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp;
+
+ if( GL_FALSE == assemble_src(pAsm, 0, -1) )
+ {
+ return GL_FALSE;
+ }
+
+ setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_1);
+
+ if( GL_FALSE == assemble_src(pAsm, 0, 2) )
+ {
+ return GL_FALSE;
+ }
+
+ if( GL_FALSE == next_ins(pAsm) )
+ {
+ return GL_FALSE;
+ }
+
+ /* dst = (-tmp > 0 ? -1 : tmp) */
+ pAsm->D.dst.opcode = SQ_OP3_INST_CNDGT;
+ pAsm->D.dst.op3 = 1;
+
+ if( GL_FALSE == assemble_dst(pAsm) )
+ {
+ return GL_FALSE;
+ }
+
+ setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+ pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[0].src.reg = tmp;
+ noswizzle_PVSSRC(&(pAsm->S[0].src));
+ neg_PVSSRC(&(pAsm->S[0].src));
+
+ setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_1);
+ neg_PVSSRC(&(pAsm->S[1].src));
+
+ setaddrmode_PVSSRC(&(pAsm->S[2].src), ADDR_ABSOLUTE);
+ pAsm->S[2].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[2].src.reg = tmp;
+ noswizzle_PVSSRC(&(pAsm->S[2].src));
+
+ if( GL_FALSE == next_ins(pAsm) )
+ {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
GLboolean assemble_STP(r700_AssemblerBase *pAsm)
{
return GL_TRUE;
@@ -4387,7 +5097,14 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
if (pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXP)
{
GLuint tmp = gethelpr(pAsm);
- pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_RECIP_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
+ }
pAsm->D.dst.math = 1;
setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
pAsm->D.dst.rtype = DST_REG_TEMPORARY;
@@ -4437,7 +5154,14 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
GLuint tmp2 = gethelpr(pAsm);
/* tmp1.xyzw = CUBE(R0.zzxy, R0.yxzz) */
- pAsm->D.dst.opcode = SQ_OP2_INST_CUBE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_CUBE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_CUBE;
+ }
setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
pAsm->D.dst.rtype = DST_REG_TEMPORARY;
pAsm->D.dst.reg = tmp1;
@@ -4462,7 +5186,14 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
}
/* tmp1.z = RCP_e(|tmp1.z|) */
- pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP2_INST_RECIP_IEEE;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
+ }
pAsm->D.dst.math = 1;
setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
pAsm->D.dst.rtype = DST_REG_TEMPORARY;
@@ -4481,7 +5212,14 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
* MULADD R0.y, R0.y, PS1, (0x3FC00000, 1.5f).x
* muladd has no writemask, have to use another temp
*/
- pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP3_INST_MULADD;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ }
pAsm->D.dst.op3 = 1;
setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
pAsm->D.dst.rtype = DST_REG_TEMPORARY;
@@ -4668,7 +5406,14 @@ GLboolean assemble_XPD(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ if(8 == pAsm->unAsic)
+ {
+ pAsm->D.dst.opcode = EG_OP3_INST_MULADD;
+ }
+ else
+ {
+ pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ }
pAsm->D.dst.op3 = 1;
if(0xF != pAsm->pILInst[pAsm->uiCurInst].DstReg.WriteMask)
@@ -4825,16 +5570,49 @@ GLboolean jumpToOffest(r700_AssemblerBase *pAsm, GLuint pops, GLint offset)
return GL_FALSE;
}
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = pops;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_JUMP,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ pops,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = pops;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_JUMP;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_JUMP;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + offset;
@@ -4848,17 +5626,50 @@ GLboolean pops(r700_AssemblerBase *pAsm, GLuint pops)
return GL_FALSE;
}
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = pops;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_POP,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ pops,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = pops;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
return GL_TRUE;
@@ -4876,23 +5687,66 @@ GLboolean assemble_IF(r700_AssemblerBase *pAsm, GLboolean bHasElse)
return GL_FALSE;
}
- if(GL_TRUE != bHasElse)
- {
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
+ if(8 == pAsm->unAsic)
+ {
+ if(GL_TRUE != bHasElse)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ }
+ else
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ }
+
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_JUMP,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
}
else
{
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
- }
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(GL_TRUE != bHasElse)
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
+ }
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_JUMP;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_JUMP;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->FCSP++;
pAsm->fc_stack[pAsm->FCSP].type = FC_IF;
@@ -4919,16 +5773,49 @@ GLboolean assemble_ELSE(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1; ///
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_ELSE,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1; ///
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_ELSE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_ELSE;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->fc_stack[pAsm->FCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc( (void *)pAsm->fc_stack[pAsm->FCSP].mid,
0,
@@ -4988,17 +5875,49 @@ GLboolean assemble_BGNLOOP(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
-
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_LOOP_START_NO_AL,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_START_NO_AL;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_START_NO_AL;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->FCSP++;
pAsm->fc_stack[pAsm->FCSP].type = FC_LOOP;
@@ -5039,18 +5958,50 @@ GLboolean assemble_BRK(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
-
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_LOOP_BREAK,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_BREAK;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_BREAK;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc(
(void *)pAsm->fc_stack[unFCSP].mid,
@@ -5064,18 +6015,52 @@ GLboolean assemble_BRK(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_POP,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
- pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
+
+ pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
checkStackDepth(pAsm, FC_PUSH_VPM, GL_TRUE);
@@ -5109,18 +6094,50 @@ GLboolean assemble_CONT(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
-
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_LOOP_CONTINUE,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_CONTINUE;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_CONTINUE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc(
(void *)pAsm->fc_stack[unFCSP].mid,
@@ -5134,17 +6151,51 @@ GLboolean assemble_CONT(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_POP,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_POP;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
checkStackDepth(pAsm, FC_PUSH_VPM, GL_TRUE);
@@ -5163,17 +6214,49 @@ GLboolean assemble_ENDLOOP(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
-
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_LOOP_END,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_END;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_END;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->cf_current_cf_clause_ptr->m_Word0.f.addr = pAsm->fc_stack[pAsm->FCSP].first->m_uIndex + 1;
pAsm->fc_stack[pAsm->FCSP].first->m_Word0.f.addr = pAsm->cf_current_cf_clause_ptr->m_uIndex + 1;
@@ -5235,17 +6318,51 @@ void add_return_inst(r700_AssemblerBase *pAsm)
{
return;
}
- //pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_RETURN;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_RETURN,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ //pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_RETURN;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
}
GLboolean assemble_BGNSUB(r700_AssemblerBase *pAsm, GLint nILindex, GLuint uiIL_Shift)
@@ -5368,17 +6485,50 @@ GLboolean assemble_CAL(r700_AssemblerBase *pAsm,
return GL_FALSE;
}
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.call_count = 1;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_CALL,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.call_count = 1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_CALL;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_CALL;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
/* Put in caller */
if( (pAsm->unCallerArrayPointer + 1) > pAsm->unCallerArraySize )
@@ -5579,16 +6729,49 @@ GLboolean breakLoopOnFlag(r700_AssemblerBase *pAsm, GLuint unFCSP)
return GL_FALSE;
}
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__POP_COUNT_shift, EG_CF_WORD1__POP_COUNT_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ EG_CF_INST_LOOP_BREAK,
+ EG_CF_WORD1__CF_INST_shift, EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__CF_CONST_shift, EG_CF_WORD1__CF_CONST_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ SQ_CF_COND_ACTIVE,
+ EG_CF_WORD1__COND_shift, EG_CF_WORD1__COND_mask);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__EOP_shift, EG_CF_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__VPM_shift, EG_CF_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_WORD1__WQM_shift, EG_CF_WORD1__WQM_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__BARRIER_shift, EG_CF_WORD1__BARRIER_bit);
+ SETfield(pAsm->cf_current_cf_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_WORD1__COUNT_shift, EG_CF_WORD1__COUNT_mask);
+ }
+ else
+ {
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.pop_count = 1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_const = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cond = SQ_CF_COND_ACTIVE;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_BREAK;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_LOOP_BREAK;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ pAsm->cf_current_cf_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
pAsm->fc_stack[unFCSP].mid = (R700ControlFlowGenericClause **)_mesa_realloc(
(void *)pAsm->fc_stack[unFCSP].mid,
@@ -5677,10 +6860,19 @@ GLboolean AssembleInstr(GLuint uiFirstInst,
return GL_FALSE;
break;
case OPCODE_COS:
- if ( GL_FALSE == assemble_TRIG(pR700AsmCode, SQ_OP2_INST_COS) )
- return GL_FALSE;
+ if(8 == pR700AsmCode->unAsic)
+ {
+ if ( GL_FALSE == assemble_TRIG(pR700AsmCode, EG_OP2_INST_COS) )
+ return GL_FALSE;
+ }
+ else
+ {
+ if ( GL_FALSE == assemble_TRIG(pR700AsmCode, SQ_OP2_INST_COS) )
+ return GL_FALSE;
+ }
break;
+ case OPCODE_DP2:
case OPCODE_DP3:
case OPCODE_DP4:
case OPCODE_DPH:
@@ -5794,8 +6986,16 @@ GLboolean AssembleInstr(GLuint uiFirstInst,
return GL_FALSE;
break;
case OPCODE_SIN:
- if ( GL_FALSE == assemble_TRIG(pR700AsmCode, SQ_OP2_INST_SIN) )
- return GL_FALSE;
+ if(8 == pR700AsmCode->unAsic)
+ {
+ if ( GL_FALSE == assemble_TRIG(pR700AsmCode, EG_OP2_INST_SIN) )
+ return GL_FALSE;
+ }
+ else
+ {
+ if ( GL_FALSE == assemble_TRIG(pR700AsmCode, SQ_OP2_INST_SIN) )
+ return GL_FALSE;
+ }
break;
case OPCODE_SCS:
if ( GL_FALSE == assemble_SCS(pR700AsmCode) )
@@ -5872,6 +7072,13 @@ GLboolean AssembleInstr(GLuint uiFirstInst,
// return GL_FALSE;
// break;
+ case OPCODE_SSG:
+ if ( GL_FALSE == assemble_SSG(pR700AsmCode) )
+ {
+ return GL_FALSE;
+ }
+ break;
+
case OPCODE_SWZ:
if ( GL_FALSE == assemble_MOV(pR700AsmCode) )
{
@@ -6006,7 +7213,7 @@ GLboolean AssembleInstr(GLuint uiFirstInst,
return GL_TRUE;
default:
- radeon_error("internal: unknown instruction\n");
+ radeon_error("r600: unknown instruction %d\n", pILInst[i].Opcode);
return GL_FALSE;
}
}
@@ -6016,7 +7223,15 @@ GLboolean AssembleInstr(GLuint uiFirstInst,
GLboolean InitShaderProgram(r700_AssemblerBase * pAsm)
{
+#ifndef GENERATE_SHADER_FOR_2D
setRetInLoopFlag(pAsm, SQ_SEL_0);
+#endif
+
+ if((SPT_FP == pAsm->currentShaderType) && (8 == pAsm->unAsic))
+ {
+ EG_add_ps_interp(pAsm);
+ }
+
pAsm->alu_x_opcode = SQ_CF_INST_ALU;
return GL_TRUE;
}
@@ -6039,6 +7254,7 @@ GLboolean RelocProgram(r700_AssemblerBase * pAsm, struct gl_program * pILProg)
plstCFmain = pAsm->CALLSTACK[0].plstCFInstructions_local;
+#ifndef GENERATE_SHADER_FOR_2D
/* remove flags init if they are not used */
if((pAsm->unCFflags & HAS_LOOPRET) == 0)
{
@@ -6069,6 +7285,7 @@ GLboolean RelocProgram(r700_AssemblerBase * pAsm, struct gl_program * pILProg)
pInst = pInst->pNextInst;
};
}
+#endif /* GENERATE_SHADER_FOR_2D */
if(pAsm->CALLSTACK[0].max > 0)
{
@@ -6175,13 +7392,20 @@ GLboolean RelocProgram(r700_AssemblerBase * pAsm, struct gl_program * pILProg)
}
else
{
- if(pAsm->bR6xx)
+ if(8 == pAsm->unAsic)
{
- uNumSrc = r700GetNumOperands(pALU->m_Word1_OP2.f6.alu_inst, 0);
+ uNumSrc = EG_GetNumOperands(pALU->m_Word1_OP2.f.alu_inst, 0);
}
else
{
- uNumSrc = r700GetNumOperands(pALU->m_Word1_OP2.f.alu_inst, 0);
+ if(pAsm->bR6xx)
+ {
+ uNumSrc = r700GetNumOperands(pALU->m_Word1_OP2.f6.alu_inst, 0);
+ }
+ else
+ {
+ uNumSrc = r700GetNumOperands(pALU->m_Word1_OP2.f.alu_inst, 0);
+ }
}
if(2 == uNumSrc)
{ /* 2 srcs */
@@ -6472,12 +7696,42 @@ GLboolean Process_Export(r700_AssemblerBase* pAsm,
pAsm->cf_current_export_clause_ptr->m_Word0.f.index_gpr = 0x0;
pAsm->cf_current_export_clause_ptr->m_Word0.f.elem_size = 0x3;
- pAsm->cf_current_export_clause_ptr->m_Word1.f.burst_count = (export_count - 1);
- pAsm->cf_current_export_clause_ptr->m_Word1.f.end_of_program = 0x0;
- pAsm->cf_current_export_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
- pAsm->cf_current_export_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT; // _DONE
- pAsm->cf_current_export_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
- pAsm->cf_current_export_clause_ptr->m_Word1.f.barrier = 0x1;
+ if(8 == pAsm->unAsic)
+ {
+ SETfield(pAsm->cf_current_export_clause_ptr->m_Word1.val,
+ (export_count - 1),
+ EG_CF_ALLOC_EXPORT_WORD1__BURST_COUNT_shift,
+ EG_CF_ALLOC_EXPORT_WORD1__BURST_COUNT_mask);
+ SETfield(pAsm->cf_current_export_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_ALLOC_EXPORT_WORD1__EOP_shift,
+ EG_CF_ALLOC_EXPORT_WORD1__EOP_bit);
+ SETfield(pAsm->cf_current_export_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_ALLOC_EXPORT_WORD1__VPM_shift,
+ EG_CF_ALLOC_EXPORT_WORD1__VPM_bit);
+ SETfield(pAsm->cf_current_export_clause_ptr->m_Word1.val,
+ EG_CF_INST_EXPORT,
+ EG_CF_WORD1__CF_INST_shift,
+ EG_CF_WORD1__CF_INST_mask);
+ SETfield(pAsm->cf_current_export_clause_ptr->m_Word1.val,
+ 0,
+ EG_CF_ALLOC_EXPORT_WORD1__MARK_shift,
+ EG_CF_ALLOC_EXPORT_WORD1__MARK_bit);
+ SETfield(pAsm->cf_current_export_clause_ptr->m_Word1.val,
+ 1,
+ EG_CF_ALLOC_EXPORT_WORD1__BARRIER_shift,
+ EG_CF_ALLOC_EXPORT_WORD1__BARRIER_bit);
+ }
+ else
+ {
+ pAsm->cf_current_export_clause_ptr->m_Word1.f.burst_count = (export_count - 1);
+ pAsm->cf_current_export_clause_ptr->m_Word1.f.end_of_program = 0x0;
+ pAsm->cf_current_export_clause_ptr->m_Word1.f.valid_pixel_mode = 0x0;
+ pAsm->cf_current_export_clause_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT; // _DONE
+ pAsm->cf_current_export_clause_ptr->m_Word1.f.whole_quad_mode = 0x0;
+ pAsm->cf_current_export_clause_ptr->m_Word1.f.barrier = 0x1;
+ }
if (export_count == 1)
{
@@ -6605,8 +7859,22 @@ GLboolean Process_Fragment_Exports(r700_AssemblerBase *pR700AsmCode,
if(pR700AsmCode->cf_last_export_ptr != NULL)
{
- pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
- pR700AsmCode->cf_last_export_ptr->m_Word1.f.end_of_program = 0x1;
+ if(8 == pR700AsmCode->unAsic)
+ {
+ SETfield(pR700AsmCode->cf_last_export_ptr->m_Word1.val,
+ 1,
+ EG_CF_ALLOC_EXPORT_WORD1__EOP_shift,
+ EG_CF_ALLOC_EXPORT_WORD1__EOP_bit);
+ SETfield(pR700AsmCode->cf_last_export_ptr->m_Word1.val,
+ EG_CF_INST_EXPORT_DONE,
+ EG_CF_WORD1__CF_INST_shift,
+ EG_CF_WORD1__CF_INST_mask);
+ }
+ else
+ {
+ pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
+ pR700AsmCode->cf_last_export_ptr->m_Word1.f.end_of_program = 0x1;
+ }
}
return GL_TRUE;
@@ -6652,7 +7920,17 @@ GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode,
export_count--;
}
- pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
+ if(8 == pR700AsmCode->unAsic)
+ {
+ SETfield(pR700AsmCode->cf_last_export_ptr->m_Word1.val,
+ EG_CF_INST_EXPORT_DONE,
+ EG_CF_WORD1__CF_INST_shift,
+ EG_CF_WORD1__CF_INST_mask);
+ }
+ else
+ {
+ pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
+ }
pR700AsmCode->number_of_exports = export_count;
@@ -6747,7 +8025,17 @@ GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode,
// At least one param should be exported
if (export_count)
{
- pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
+ if(8 == pR700AsmCode->unAsic)
+ {
+ SETfield(pR700AsmCode->cf_last_export_ptr->m_Word1.val,
+ EG_CF_INST_EXPORT_DONE,
+ EG_CF_WORD1__CF_INST_shift,
+ EG_CF_WORD1__CF_INST_mask);
+ }
+ else
+ {
+ pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
+ }
}
else
{
@@ -6765,7 +8053,17 @@ GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode,
pR700AsmCode->cf_last_export_ptr->m_Word1_SWIZ.f.sel_y = SQ_SEL_0;
pR700AsmCode->cf_last_export_ptr->m_Word1_SWIZ.f.sel_z = SQ_SEL_0;
pR700AsmCode->cf_last_export_ptr->m_Word1_SWIZ.f.sel_w = SQ_SEL_1;
- pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
+ if(8 == pR700AsmCode->unAsic)
+ {
+ SETfield(pR700AsmCode->cf_last_export_ptr->m_Word1.val,
+ EG_CF_INST_EXPORT_DONE,
+ EG_CF_WORD1__CF_INST_shift,
+ EG_CF_WORD1__CF_INST_mask);
+ }
+ else
+ {
+ pR700AsmCode->cf_last_export_ptr->m_Word1.f.cf_inst = SQ_CF_INST_EXPORT_DONE;
+ }
}
pR700AsmCode->cf_last_export_ptr->m_Word1.f.end_of_program = 0x1;
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.h b/src/mesa/drivers/dri/r600/r700_assembler.h
index dbc6cdb1903..d357b0e3ec0 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.h
+++ b/src/mesa/drivers/dri/r600/r700_assembler.h
@@ -108,7 +108,7 @@ typedef enum AddressMode
typedef enum SrcRegisterType
{
SRC_REG_TEMPORARY = 0,
- SRC_REG_INPUT = 1,
+ SRC_REG_GPR = 1,
SRC_REG_CONSTANT = 2,
SRC_REG_ALT_TEMPORARY = 3,
SRC_REC_LITERAL = 4,
@@ -464,6 +464,10 @@ typedef struct r700_AssemblerBase
GLuint uiCurInst;
GLubyte SamplerUnits[MAX_SAMPLERS];
GLboolean bR6xx;
+
+ /* TODO : merge bR6xx */
+ GLuint unAsic;
+
/* helper to decide which type of instruction to assemble */
GLboolean is_tex;
/* we inserted helper intructions and need barrier on next TEX ins */
@@ -489,6 +493,9 @@ typedef struct r700_AssemblerBase
GLuint shadow_regs[R700_MAX_TEXTURE_UNITS];
+ GLboolean bUseMemConstant;
+ GLuint kcacheUsed;
+
} r700_AssemblerBase;
//Internal use
@@ -512,6 +519,8 @@ GLuint GetSurfaceFormat(GLenum eType, GLuint nChannels, GLuint * pClient_size);
unsigned int r700GetNumOperands(GLuint opcode, GLuint nIsOp3);
+unsigned int EG_GetNumOperands(GLuint opcode, GLuint nIsOp3);
+
GLboolean IsTex(gl_inst_opcode Opcode);
GLboolean IsAlu(gl_inst_opcode Opcode);
int check_current_clause(r700_AssemblerBase* pAsm,
@@ -535,6 +544,18 @@ GLboolean assemble_vfetch_instruction2(r700_AssemblerBase* pAsm,
GLboolean normalize,
GLenum format,
VTX_FETCH_METHOD * pFetchMethod);
+
+GLboolean EG_assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
+ GLuint destination_register,
+ GLenum type,
+ GLint size,
+ GLubyte element,
+ GLuint _signed,
+ GLboolean normalize,
+ GLenum format,
+ VTX_FETCH_METHOD * pFetchMethod);
+//-----------------------
+
GLboolean cleanup_vfetch_instructions(r700_AssemblerBase* pAsm);
GLuint gethelpr(r700_AssemblerBase* pAsm);
void resethelpr(r700_AssemblerBase* pAsm);
@@ -553,8 +574,10 @@ GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm, GLboolean normalize
void initialize(r700_AssemblerBase *pAsm);
GLboolean assemble_alu_src(R700ALUInstruction* alu_instruction_ptr,
int source_index,
- PVSSRC* pSource,
- BITS scalar_channel_index);
+ PVSSRC* pSource,
+ BITS scalar_channel_index,
+ r700_AssemblerBase *pAsm);
+
GLboolean add_alu_instruction(r700_AssemblerBase* pAsm,
R700ALUInstruction* alu_instruction_ptr,
GLuint contiguous_slots_needed);
@@ -625,6 +648,7 @@ GLboolean assemble_LOGIC_PRED(r700_AssemblerBase *pAsm, BITS opcode);
GLboolean assemble_TRIG(r700_AssemblerBase *pAsm, BITS opcode);
GLboolean assemble_SLT(r700_AssemblerBase *pAsm);
+GLboolean assemble_SSG(r700_AssemblerBase *pAsm);
GLboolean assemble_STP(r700_AssemblerBase *pAsm);
GLboolean assemble_TEX(r700_AssemblerBase *pAsm);
GLboolean assemble_XPD(r700_AssemblerBase *pAsm);
@@ -663,6 +687,7 @@ GLboolean callPreSub(r700_AssemblerBase* pAsm,
COMPILED_SUB * pCompiledSub,
GLshort uOutReg,
GLshort uNumValidSrc);
+GLboolean EG_add_ps_interp(r700_AssemblerBase* pAsm);
//Interface
GLboolean AssembleInstr(GLuint uiFirstInst,
diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c
index bf8063391a2..71f1af75626 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.c
+++ b/src/mesa/drivers/dri/r600/r700_chip.c
@@ -173,7 +173,6 @@ static void r700SetupVTXConstants(GLcontext * ctx,
{
context_t *context = R700_CONTEXT(ctx);
struct radeon_aos * paos = (struct radeon_aos *)pAos;
- unsigned int nVBsize;
BATCH_LOCALS(&context->radeon);
unsigned int uSQ_VTX_CONSTANT_WORD0_0;
@@ -194,18 +193,8 @@ static void r700SetupVTXConstants(GLcontext * ctx,
else
r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit);
- if(0 == pStreamDesc->stride)
- {
- nVBsize = paos->count * pStreamDesc->size * getTypeSize(pStreamDesc->type);
- }
- else
- {
- nVBsize = (paos->count - 1) * pStreamDesc->stride
- + pStreamDesc->size * getTypeSize(pStreamDesc->type);
- }
-
uSQ_VTX_CONSTANT_WORD0_0 = paos->offset;
- uSQ_VTX_CONSTANT_WORD1_0 = nVBsize - 1;
+ uSQ_VTX_CONSTANT_WORD1_0 = paos->bo->size - paos->offset - 1;
SETfield(uSQ_VTX_CONSTANT_WORD2_0, 0, BASE_ADDRESS_HI_shift, BASE_ADDRESS_HI_mask); /* TODO */
SETfield(uSQ_VTX_CONSTANT_WORD2_0, pStreamDesc->stride, SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift,
@@ -721,6 +710,7 @@ static void r700SendPSState(GLcontext *ctx, struct radeon_state_atom *atom)
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
struct radeon_bo * pbo;
+ struct radeon_bo * pbo_const;
BATCH_LOCALS(&context->radeon);
radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
@@ -750,6 +740,9 @@ static void r700SendPSState(GLcontext *ctx, struct radeon_state_atom *atom)
R600_OUT_BATCH_REGVAL(SQ_LOOP_CONST_0, 0x01000FFF);
END_BATCH();
+ pbo_const = (struct radeon_bo *)r700GetActiveFpShaderConstBo(GL_CONTEXT(context));
+ //TODO : set up shader const
+
COMMIT_BATCH();
}
@@ -759,13 +752,14 @@ static void r700SendVSState(GLcontext *ctx, struct radeon_state_atom *atom)
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
struct radeon_bo * pbo;
+ struct radeon_bo * pbo_const;
BATCH_LOCALS(&context->radeon);
radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
pbo = (struct radeon_bo *)r700GetActiveVpShaderBo(GL_CONTEXT(context));
if (!pbo)
- return;
+ return;
r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
@@ -788,6 +782,29 @@ static void r700SendVSState(GLcontext *ctx, struct radeon_state_atom *atom)
//R600_OUT_BATCH_REGVAL((SQ_LOOP_CONST_0 + (SQ_LOOP_CONST_vs<2)), 0x0100000F);
END_BATCH();
+ /* TODO : handle 4 bufs */
+ if(GL_TRUE == r700->bShaderUseMemConstant)
+ {
+ pbo_const = (struct radeon_bo *)r700GetActiveVpShaderConstBo(GL_CONTEXT(context));
+ if(NULL != pbo_const)
+ {
+ r700SyncSurf(context, pbo_const, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit); /* TODO : Check kc bit. */
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ R600_OUT_BATCH_REGVAL(SQ_ALU_CONST_BUFFER_SIZE_VS_0, (r700->vs.num_consts * 4)/16 );
+ END_BATCH();
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
+ R600_OUT_BATCH_REGSEQ(SQ_ALU_CONST_CACHE_VS_0, 1);
+ R600_OUT_BATCH(r700->vs.SQ_ALU_CONST_CACHE_VS_0.u32All);
+ R600_OUT_BATCH_RELOC(r700->vs.SQ_ALU_CONST_CACHE_VS_0.u32All,
+ pbo_const,
+ r700->vs.SQ_ALU_CONST_CACHE_VS_0.u32All,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+ }
+ }
+
COMMIT_BATCH();
}
@@ -1558,45 +1575,55 @@ static void r600_init_query_stateobj(radeonContextPtr radeon, int SZ)
void r600InitAtoms(context_t *context)
{
- radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %p\n", __func__, context);
- context->radeon.hw.max_state_size = 10 + 5 + 14; /* start 3d, idle, cb/db flush */
-
- /* Setup the atom linked list */
- make_empty_list(&context->radeon.hw.atomlist);
- context->radeon.hw.atomlist.name = "atom-list";
-
- ALLOC_STATE(sq, always, 34, r700SendSQConfig);
- ALLOC_STATE(db, always, 17, r700SendDBState);
- ALLOC_STATE(stencil, always, 4, r700SendStencilState);
- ALLOC_STATE(db_target, always, 16, r700SendDepthTargetState);
- ALLOC_STATE(sc, always, 15, r700SendSCState);
- ALLOC_STATE(scissor, always, 22, r700SendScissorState);
- ALLOC_STATE(aa, always, 12, r700SendAAState);
- ALLOC_STATE(cl, always, 12, r700SendCLState);
- ALLOC_STATE(gb, always, 6, r700SendGBState);
- ALLOC_STATE(ucp, ucp, (R700_MAX_UCP * 6), r700SendUCPState);
- ALLOC_STATE(su, always, 9, r700SendSUState);
- ALLOC_STATE(poly, always, 10, r700SendPolyState);
- ALLOC_STATE(cb, cb, 18, r700SendCBState);
- ALLOC_STATE(clrcmp, always, 6, r700SendCBCLRCMPState);
- ALLOC_STATE(cb_target, always, 31, r700SendRenderTargetState);
- ALLOC_STATE(blnd, blnd, (6 + (R700_MAX_RENDER_TARGETS * 3)), r700SendCBBlendState);
- ALLOC_STATE(blnd_clr, always, 6, r700SendCBBlendColorState);
- ALLOC_STATE(sx, always, 9, r700SendSXState);
- ALLOC_STATE(vgt, always, 41, r700SendVGTState);
- ALLOC_STATE(spi, always, (59 + R700_MAX_SHADER_EXPORTS), r700SendSPIState);
- ALLOC_STATE(vpt, always, 16, r700SendViewportState);
- ALLOC_STATE(fs, always, 18, r700SendFSState);
- ALLOC_STATE(vs, always, 21, r700SendVSState);
- ALLOC_STATE(ps, always, 24, r700SendPSState);
- ALLOC_STATE(vs_consts, vs_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendVSConsts);
- ALLOC_STATE(ps_consts, ps_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendPSConsts);
- ALLOC_STATE(vtx, vtx, (VERT_ATTRIB_MAX * 18), r700SendVTXState);
- ALLOC_STATE(tx, tx, (R700_TEXTURE_NUMBERUNITS * 20), r700SendTexState);
- ALLOC_STATE(tx_smplr, tx, (R700_TEXTURE_NUMBERUNITS * 5), r700SendTexSamplerState);
- ALLOC_STATE(tx_brdr_clr, tx, (R700_TEXTURE_NUMBERUNITS * 6), r700SendTexBorderColorState);
- r600_init_query_stateobj(&context->radeon, 6 * 2);
-
- context->radeon.hw.is_dirty = GL_TRUE;
- context->radeon.hw.all_dirty = GL_TRUE;
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %p\n", __func__, context);
+ context->radeon.hw.max_state_size = 10 + 5 + 14; /* start 3d, idle, cb/db flush */
+
+ /* Setup the atom linked list */
+ make_empty_list(&context->radeon.hw.atomlist);
+ context->radeon.hw.atomlist.name = "atom-list";
+
+ ALLOC_STATE(sq, always, 34, r700SendSQConfig);
+ ALLOC_STATE(db, always, 17, r700SendDBState);
+ ALLOC_STATE(stencil, always, 4, r700SendStencilState);
+ ALLOC_STATE(db_target, always, 16, r700SendDepthTargetState);
+ ALLOC_STATE(sc, always, 15, r700SendSCState);
+ ALLOC_STATE(scissor, always, 22, r700SendScissorState);
+ ALLOC_STATE(aa, always, 12, r700SendAAState);
+ ALLOC_STATE(cl, always, 12, r700SendCLState);
+ ALLOC_STATE(gb, always, 6, r700SendGBState);
+ ALLOC_STATE(ucp, ucp, (R700_MAX_UCP * 6), r700SendUCPState);
+ ALLOC_STATE(su, always, 9, r700SendSUState);
+ ALLOC_STATE(poly, always, 10, r700SendPolyState);
+ ALLOC_STATE(cb, cb, 18, r700SendCBState);
+ ALLOC_STATE(clrcmp, always, 6, r700SendCBCLRCMPState);
+ ALLOC_STATE(cb_target, always, 31, r700SendRenderTargetState);
+ ALLOC_STATE(blnd, blnd, (6 + (R700_MAX_RENDER_TARGETS * 3)), r700SendCBBlendState);
+ ALLOC_STATE(blnd_clr, always, 6, r700SendCBBlendColorState);
+ ALLOC_STATE(sx, always, 9, r700SendSXState);
+ ALLOC_STATE(vgt, always, 41, r700SendVGTState);
+ ALLOC_STATE(spi, always, (59 + R700_MAX_SHADER_EXPORTS), r700SendSPIState);
+ ALLOC_STATE(vpt, always, 16, r700SendViewportState);
+ ALLOC_STATE(fs, always, 18, r700SendFSState);
+ if(GL_TRUE == r700->bShaderUseMemConstant)
+ {
+ ALLOC_STATE(vs, always, 36, r700SendVSState);
+ ALLOC_STATE(ps, always, 24, r700SendPSState); /* TODO : not imp yet, fix later. */
+ }
+ else
+ {
+ ALLOC_STATE(vs, always, 21, r700SendVSState);
+ ALLOC_STATE(ps, always, 24, r700SendPSState);
+ ALLOC_STATE(vs_consts, vs_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendVSConsts);
+ ALLOC_STATE(ps_consts, ps_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendPSConsts);
+ }
+
+ ALLOC_STATE(vtx, vtx, (VERT_ATTRIB_MAX * 18), r700SendVTXState);
+ ALLOC_STATE(tx, tx, (R700_TEXTURE_NUMBERUNITS * 20), r700SendTexState);
+ ALLOC_STATE(tx_smplr, tx, (R700_TEXTURE_NUMBERUNITS * 5), r700SendTexSamplerState);
+ ALLOC_STATE(tx_brdr_clr, tx, (R700_TEXTURE_NUMBERUNITS * 6), r700SendTexBorderColorState);
+ r600_init_query_stateobj(&context->radeon, 6 * 2);
+
+ context->radeon.hw.is_dirty = GL_TRUE;
+ context->radeon.hw.all_dirty = GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/r600/r700_chip.h b/src/mesa/drivers/dri/r600/r700_chip.h
index 0b6b72f8501..ebf1840a795 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.h
+++ b/src/mesa/drivers/dri/r600/r700_chip.h
@@ -43,6 +43,8 @@
#define SETbit(x, bit) ( (x) |= (bit) )
#define CLEARbit(x, bit) ( (x) &= ~(bit) )
+#define GETbits(x, shift, mask) ( ((x) & (mask)) >> (shift) )
+
#define R700_TEXTURE_NUMBERUNITS 16
#define R700_MAX_RENDER_TARGETS 8
#define R700_MAX_VIEWPORTS 16
@@ -238,6 +240,9 @@ typedef struct _VS_STATE_STRUCT
union UINT_FLOAT SQ_PGM_CF_OFFSET_VS ; /* 0xA234 */
GLboolean dirty;
int num_consts;
+
+ union UINT_FLOAT SQ_ALU_CONST_CACHE_VS_0;
+
union UINT_FLOAT consts[R700_MAX_DX9_CONSTS][4];
} VS_STATE_STRUCT;
@@ -499,6 +504,8 @@ typedef struct _R700_CHIP_CONTEXT
GLboolean bEnablePerspective;
+ GLboolean bShaderUseMemConstant;
+
} R700_CHIP_CONTEXT;
#endif /* _R700_CHIP_H_ */
diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.c b/src/mesa/drivers/dri/r600/r700_fragprog.c
index f9d84b6ed68..6fdd93a3302 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.c
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.c
@@ -362,6 +362,9 @@ GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
struct gl_fragment_program *mesa_fp,
GLcontext *ctx)
{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+
GLuint number_of_colors_exported;
GLboolean z_enabled = GL_FALSE;
GLuint unBit, shadow_unit;
@@ -373,6 +376,17 @@ GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
//Init_Program
Init_r700_AssemblerBase( SPT_FP, &(fp->r700AsmCode), &(fp->r700Shader) );
+ if(GL_TRUE == r700->bShaderUseMemConstant)
+ {
+ fp->r700AsmCode.bUseMemConstant = GL_TRUE;
+ }
+ else
+ {
+ fp->r700AsmCode.bUseMemConstant = GL_FALSE;
+ }
+
+ fp->r700AsmCode.unAsic = 7;
+
if(mesa_fp->Base.InputsRead & FRAG_BIT_WPOS)
{
insert_wpos_code(ctx, mesa_fp);
@@ -481,6 +495,14 @@ void * r700GetActiveFpShaderBo(GLcontext * ctx)
return fp->shaderbo;
}
+void * r700GetActiveFpShaderConstBo(GLcontext * ctx)
+{
+ struct r700_fragment_program *fp = (struct r700_fragment_program *)
+ (ctx->FragmentProgram._Current);
+
+ return fp->constbo0;
+}
+
GLboolean r700SetupFragmentProgram(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
@@ -768,6 +790,17 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
}
+
+ /* Load fp constants to gpu */
+ if( (GL_TRUE == r700->bShaderUseMemConstant) && (unNumParamData > 0) )
+ {
+ r600EmitShader(ctx,
+ &(fp->constbo0),
+ (GLvoid *)&(paramList->ParameterValues[0][0]),
+ unNumParamData * 4,
+ "FS Const");
+ }
+
} else
r700->ps.num_consts = 0;
diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.h b/src/mesa/drivers/dri/r600/r700_fragprog.h
index 39c59c9201d..aaa6043d5d8 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.h
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.h
@@ -43,6 +43,9 @@ struct r700_fragment_program
void * shaderbo;
+ GLuint k0used;
+ void * constbo0;
+
GLboolean WritesDepth;
GLuint optimization;
};
@@ -67,4 +70,6 @@ extern GLboolean r700SetupFragmentProgram(GLcontext * ctx);
extern void * r700GetActiveFpShaderBo(GLcontext * ctx);
+extern void * r700GetActiveFpShaderConstBo(GLcontext * ctx);
+
#endif /*_R700_FRAGPROG_H_*/
diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c
index 83517925115..e0c9179004d 100644
--- a/src/mesa/drivers/dri/r600/r700_oglprog.c
+++ b/src/mesa/drivers/dri/r600/r700_oglprog.c
@@ -48,6 +48,12 @@ static void freeVertProgCache(GLcontext *ctx, struct r700_vertex_program_cont *c
tmp = vp->next;
/* Release DMA region */
r600DeleteShader(ctx, vp->shaderbo);
+
+ if(NULL != vp->constbo0)
+ {
+ r600DeleteShader(ctx, vp->constbo0);
+ }
+
/* Clean up */
Clean_Up_Assembler(&(vp->r700AsmCode));
Clean_Up_Shader(&(vp->r700Shader));
@@ -79,6 +85,7 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
&vpc->mesa_program,
target,
id);
+
break;
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
@@ -92,6 +99,8 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
fp->shaderbo = NULL;
+ fp->constbo0 = NULL;
+
break;
default:
_mesa_problem(ctx, "Bad target in r700NewProgram");
@@ -121,6 +130,11 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
r600DeleteShader(ctx, fp->shaderbo);
+ if(NULL != fp->constbo0)
+ {
+ r600DeleteShader(ctx, fp->constbo0);
+ }
+
/* Clean up */
Clean_Up_Assembler(&(fp->r700AsmCode));
Clean_Up_Shader(&(fp->r700Shader));
@@ -145,6 +159,13 @@ r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
break;
case GL_FRAGMENT_PROGRAM_ARB:
r600DeleteShader(ctx, fp->shaderbo);
+
+ if(NULL != fp->constbo0)
+ {
+ r600DeleteShader(ctx, fp->constbo0);
+ fp->constbo0 = NULL;
+ }
+
Clean_Up_Assembler(&(fp->r700AsmCode));
Clean_Up_Shader(&(fp->r700Shader));
fp->translated = GL_FALSE;
diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c
index c5771f9fd0b..f90c69c4166 100644
--- a/src/mesa/drivers/dri/r600/r700_render.c
+++ b/src/mesa/drivers/dri/r600/r700_render.c
@@ -644,6 +644,7 @@ static void r700SetupStreams(GLcontext *ctx, const struct gl_client_array *input
#endif
)
{
+ assert(count);
r700ConvertAttrib(ctx, count, input[i], &context->stream_desc[index]);
}
else
diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c
index 5ea8918611c..925b4ffe6dd 100644
--- a/src/mesa/drivers/dri/r600/r700_state.c
+++ b/src/mesa/drivers/dri/r600/r700_state.c
@@ -1580,7 +1580,16 @@ static void r700InitSQConfig(GLcontext * ctx)
CLEARbit(r700->sq_config.SQ_CONFIG.u32All, VC_ENABLE_bit);
else
SETbit(r700->sq_config.SQ_CONFIG.u32All, VC_ENABLE_bit);
- SETbit(r700->sq_config.SQ_CONFIG.u32All, DX9_CONSTS_bit);
+
+ if(GL_TRUE == r700->bShaderUseMemConstant)
+ {
+ CLEARbit(r700->sq_config.SQ_CONFIG.u32All, DX9_CONSTS_bit);
+ }
+ else
+ {
+ SETbit(r700->sq_config.SQ_CONFIG.u32All, DX9_CONSTS_bit);
+ }
+
SETbit(r700->sq_config.SQ_CONFIG.u32All, ALU_INST_PREFER_VECTOR_bit);
SETfield(r700->sq_config.SQ_CONFIG.u32All, ps_prio, PS_PRIO_shift, PS_PRIO_mask);
SETfield(r700->sq_config.SQ_CONFIG.u32All, vs_prio, VS_PRIO_shift, VS_PRIO_mask);
@@ -1689,8 +1698,9 @@ void r700InitState(GLcontext * ctx) //-------------------
SETbit(r700->PA_SC_MODE_CNTL.u32All, FORCE_EOV_CNTDWN_ENABLE_bit);
}
- /* Do scale XY and Z by 1/W0. */
- r700->bEnablePerspective = GL_TRUE;
+ /* Do scale XY and Z by 1/W0. */
+ r700->bEnablePerspective = GL_TRUE;
+
CLEARbit(r700->PA_CL_VTE_CNTL.u32All, VTX_XY_FMT_bit);
CLEARbit(r700->PA_CL_VTE_CNTL.u32All, VTX_Z_FMT_bit);
SETbit(r700->PA_CL_VTE_CNTL.u32All, VTX_W0_FMT_bit);
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c
index 6a2a09eaf1a..7ed4b7d2387 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.c
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.c
@@ -305,12 +305,17 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
struct gl_vertex_program *mesa_vp)
{
context_t *context = R700_CONTEXT(ctx);
+
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+
struct r700_vertex_program *vp;
unsigned int i;
vp = calloc(1, sizeof(*vp));
vp->mesa_program = _mesa_clone_vertex_program(ctx, mesa_vp);
+ vp->constbo0 = NULL;
+
if (mesa_vp->IsPositionInvariant)
{
_mesa_insert_mvp_code(ctx, vp->mesa_program);
@@ -331,6 +336,18 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
//Init_Program
Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) );
+
+ if(GL_TRUE == r700->bShaderUseMemConstant)
+ {
+ vp->r700AsmCode.bUseMemConstant = GL_TRUE;
+ }
+ else
+ {
+ vp->r700AsmCode.bUseMemConstant = GL_FALSE;
+ }
+
+ vp->r700AsmCode.unAsic = 7;
+
Map_Vertex_Program(ctx, vp, vp->mesa_program );
if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, vp->mesa_program))
@@ -576,6 +593,17 @@ void * r700GetActiveVpShaderBo(GLcontext * ctx)
return NULL;
}
+void * r700GetActiveVpShaderConstBo(GLcontext * ctx)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ struct r700_vertex_program *vp = context->selected_vp;;
+
+ if (vp)
+ return vp->constbo0;
+ else
+ return NULL;
+}
+
GLboolean r700SetupVertexProgram(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
@@ -600,6 +628,19 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
vp->r700Shader.uShaderBinaryDWORDSize,
"VS");
+ if(GL_TRUE == r700->bShaderUseMemConstant)
+ {
+ paramList = vp->mesa_program->Base.Parameters;
+ if(NULL != paramList)
+ {
+ unNumParamData = paramList->NumParameters;
+ r600AllocShaderConsts(ctx,
+ &(vp->constbo0),
+ unNumParamData *4*4,
+ "VSCON");
+ }
+ }
+
vp->loaded = GL_TRUE;
}
@@ -616,7 +657,9 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
r700->vs.SQ_PGM_RESOURCES_VS.u32All = 0;
SETbit(r700->vs.SQ_PGM_RESOURCES_VS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
- r700->vs.SQ_PGM_START_VS.u32All = 0; /* set from buffer object. */
+ r700->vs.SQ_ALU_CONST_CACHE_VS_0.u32All = 0; /* set from buffer object. */
+
+ r700->vs.SQ_PGM_START_VS.u32All = 0;
SETfield(r700->vs.SQ_PGM_RESOURCES_VS.u32All, vp->r700Shader.nRegs + 1,
NUM_GPRS_shift, NUM_GPRS_mask);
@@ -687,6 +730,16 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
}
}
+
+ /* Load vp constants to gpu */
+ if(GL_TRUE == r700->bShaderUseMemConstant)
+ {
+ r600EmitShaderConsts(ctx,
+ vp->constbo0,
+ 0,
+ (GLvoid *)&(r700->vs.consts[0][0]),
+ unNumParamData * 4 * 4);
+ }
} else
r700->vs.num_consts = 0;
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.h b/src/mesa/drivers/dri/r600/r700_vertprog.h
index 645c9ac84aa..9acdc8e3501 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.h
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.h
@@ -56,6 +56,9 @@ struct r700_vertex_program
void * shaderbo;
+ GLuint K0used;
+ void * constbo0;
+
ArrayDesc aos_desc[VERT_ATTRIB_MAX];
};
@@ -97,6 +100,8 @@ extern GLboolean r700SetupVertexProgram(GLcontext * ctx);
extern void * r700GetActiveVpShaderBo(GLcontext * ctx);
+extern void * r700GetActiveVpShaderConstBo(GLcontext * ctx);
+
extern int getTypeSize(GLenum type);
#endif /* _R700_VERTPROG_H_ */
diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h
index 7d54fabebbc..61106fbc43f 100644
--- a/src/mesa/drivers/dri/radeon/radeon_chipset.h
+++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h
@@ -400,6 +400,46 @@
#define PCI_CHIP_RV740_94B5 0x94B5
#define PCI_CHIP_RV740_94B9 0x94B9
+#define PCI_CHIP_CEDAR_68E0 0x68E0
+#define PCI_CHIP_CEDAR_68E1 0x68E1
+#define PCI_CHIP_CEDAR_68E4 0x68E4
+#define PCI_CHIP_CEDAR_68E5 0x68E5
+#define PCI_CHIP_CEDAR_68E8 0x68E8
+#define PCI_CHIP_CEDAR_68E9 0x68E9
+#define PCI_CHIP_CEDAR_68F1 0x68F1
+#define PCI_CHIP_CEDAR_68F8 0x68F8
+#define PCI_CHIP_CEDAR_68F9 0x68F9
+#define PCI_CHIP_CEDAR_68FE 0x68FE
+
+#define PCI_CHIP_REDWOOD_68C0 0x68C0
+#define PCI_CHIP_REDWOOD_68C1 0x68C1
+#define PCI_CHIP_REDWOOD_68C8 0x68C8
+#define PCI_CHIP_REDWOOD_68C9 0x68C9
+#define PCI_CHIP_REDWOOD_68D8 0x68D8
+#define PCI_CHIP_REDWOOD_68D9 0x68D9
+#define PCI_CHIP_REDWOOD_68DA 0x68DA
+#define PCI_CHIP_REDWOOD_68DE 0x68DE
+
+#define PCI_CHIP_JUNIPER_68A0 0x68A0
+#define PCI_CHIP_JUNIPER_68A1 0x68A1
+#define PCI_CHIP_JUNIPER_68A8 0x68A8
+#define PCI_CHIP_JUNIPER_68A9 0x68A9
+#define PCI_CHIP_JUNIPER_68B0 0x68B0
+#define PCI_CHIP_JUNIPER_68B8 0x68B8
+#define PCI_CHIP_JUNIPER_68B9 0x68B9
+#define PCI_CHIP_JUNIPER_68BE 0x68BE
+
+#define PCI_CHIP_CYPRESS_6880 0x6880
+#define PCI_CHIP_CYPRESS_6888 0x6888
+#define PCI_CHIP_CYPRESS_6889 0x6889
+#define PCI_CHIP_CYPRESS_688A 0x688A
+#define PCI_CHIP_CYPRESS_6898 0x6898
+#define PCI_CHIP_CYPRESS_6899 0x6899
+#define PCI_CHIP_CYPRESS_689E 0x689E
+
+#define PCI_CHIP_HEMLOCK_689C 0x689C
+#define PCI_CHIP_HEMLOCK_689D 0x689D
+
enum {
CHIP_FAMILY_R100,
CHIP_FAMILY_RV100,
@@ -438,6 +478,11 @@ enum {
CHIP_FAMILY_RV730,
CHIP_FAMILY_RV710,
CHIP_FAMILY_RV740,
+ CHIP_FAMILY_CEDAR,
+ CHIP_FAMILY_REDWOOD,
+ CHIP_FAMILY_JUNIPER,
+ CHIP_FAMILY_CYPRESS,
+ CHIP_FAMILY_HEMLOCK,
CHIP_FAMILY_LAST
};
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index 92663bf66d7..07f7cba354e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -93,6 +93,11 @@ static const char* get_chip_family_name(int chip_family)
case CHIP_FAMILY_RV730: return "RV730";
case CHIP_FAMILY_RV710: return "RV710";
case CHIP_FAMILY_RV740: return "RV740";
+ case CHIP_FAMILY_CEDAR: return "CEDAR";
+ case CHIP_FAMILY_REDWOOD: return "REDWOOD";
+ case CHIP_FAMILY_JUNIPER: return "JUNIPER";
+ case CHIP_FAMILY_CYPRESS: return "CYPRESS";
+ case CHIP_FAMILY_HEMLOCK: return "HEMLOCK";
default: return "unknown";
}
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index f06e5fdf244..024e31f8ec7 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -244,6 +244,8 @@ struct radeon_tex_obj {
GLuint SQ_TEX_RESOURCE5;
GLuint SQ_TEX_RESOURCE6;
+ GLuint SQ_TEX_RESOURCE7;
+
GLuint SQ_TEX_SAMPLER0;
GLuint SQ_TEX_SAMPLER1;
GLuint SQ_TEX_SAMPLER2;
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index 517485091a2..0597d4250de 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -609,6 +609,7 @@ radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
void radeon_fbo_init(struct radeon_context *radeon)
{
+#if FEATURE_EXT_framebuffer_object
radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer;
radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer;
radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer;
@@ -617,7 +618,10 @@ void radeon_fbo_init(struct radeon_context *radeon)
radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture;
radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers;
radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer;
+#endif
+#if FEATURE_EXT_framebuffer_blit
radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
+#endif
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index c6e5f110ea3..ddfde3edaf7 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -199,10 +199,10 @@ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_
for(face = 0; face < mt->faces; face++)
compute_tex_image_offset(rmesa, mt, face, level, &curOffset);
- /* r600 cube levels seems to be aligned to 8 faces but
- * we have separate register for 1'st level offset so add
+ /* from r700? cube levels seems to be aligned to 8 faces,
+ * as we have separate register for 1'st level offset add
* 2 image alignment after 1'st mip level */
- if(rmesa->radeonScreen->chip_family >= CHIP_FAMILY_R600 &&
+ if(rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV770 &&
mt->target == GL_TEXTURE_CUBE_MAP && level >= 1)
curOffset += 2 * mt->levels[level].size;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index fa97a19302c..2ea77e56c7e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -916,6 +916,61 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
+ case PCI_CHIP_CEDAR_68E0:
+ case PCI_CHIP_CEDAR_68E1:
+ case PCI_CHIP_CEDAR_68E4:
+ case PCI_CHIP_CEDAR_68E5:
+ case PCI_CHIP_CEDAR_68E8:
+ case PCI_CHIP_CEDAR_68E9:
+ case PCI_CHIP_CEDAR_68F1:
+ case PCI_CHIP_CEDAR_68F8:
+ case PCI_CHIP_CEDAR_68F9:
+ case PCI_CHIP_CEDAR_68FE:
+ screen->chip_family = CHIP_FAMILY_CEDAR;
+ screen->chip_flags = RADEON_CHIPSET_TCL;
+ break;
+
+ case PCI_CHIP_REDWOOD_68C0:
+ case PCI_CHIP_REDWOOD_68C1:
+ case PCI_CHIP_REDWOOD_68C8:
+ case PCI_CHIP_REDWOOD_68C9:
+ case PCI_CHIP_REDWOOD_68D8:
+ case PCI_CHIP_REDWOOD_68D9:
+ case PCI_CHIP_REDWOOD_68DA:
+ case PCI_CHIP_REDWOOD_68DE:
+ screen->chip_family = CHIP_FAMILY_REDWOOD;
+ screen->chip_flags = RADEON_CHIPSET_TCL;
+ break;
+
+ case PCI_CHIP_JUNIPER_68A0:
+ case PCI_CHIP_JUNIPER_68A1:
+ case PCI_CHIP_JUNIPER_68A8:
+ case PCI_CHIP_JUNIPER_68A9:
+ case PCI_CHIP_JUNIPER_68B0:
+ case PCI_CHIP_JUNIPER_68B8:
+ case PCI_CHIP_JUNIPER_68B9:
+ case PCI_CHIP_JUNIPER_68BE:
+ screen->chip_family = CHIP_FAMILY_JUNIPER;
+ screen->chip_flags = RADEON_CHIPSET_TCL;
+ break;
+
+ case PCI_CHIP_CYPRESS_6880:
+ case PCI_CHIP_CYPRESS_6888:
+ case PCI_CHIP_CYPRESS_6889:
+ case PCI_CHIP_CYPRESS_688A:
+ case PCI_CHIP_CYPRESS_6898:
+ case PCI_CHIP_CYPRESS_6899:
+ case PCI_CHIP_CYPRESS_689E:
+ screen->chip_family = CHIP_FAMILY_CYPRESS;
+ screen->chip_flags = RADEON_CHIPSET_TCL;
+ break;
+
+ case PCI_CHIP_HEMLOCK_689C:
+ case PCI_CHIP_HEMLOCK_689D:
+ screen->chip_family = CHIP_FAMILY_HEMLOCK;
+ screen->chip_flags = RADEON_CHIPSET_TCL;
+ break;
+
default:
fprintf(stderr, "unknown chip id 0x%x, can't guess.\n",
device_id);
@@ -1116,7 +1171,7 @@ radeonCreateScreen( __DRIscreen *sPriv )
}
}
else
- {
+ {
screen->fbLocation = (temp & 0xffff) << 16;
}
}
diff --git a/src/mesa/drivers/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile
deleted file mode 100644
index 6da9f93f59a..00000000000
--- a/src/mesa/drivers/glslcompiler/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-# Makefile for stand-alone GL-SL compiler
-
-TOP = ../../../..
-
-include $(TOP)/configs/current
-
-
-PROGRAM = glslcompiler
-
-OBJECTS = \
- glslcompiler.o \
- ../common/driverfuncs.o \
- ../../libmesa.a \
- $(TOP)/src/mapi/glapi/libglapi.a
-
-INCLUDES = \
- -I$(TOP)/include \
- -I$(TOP)/include/GL/internal \
- -I$(TOP)/src/mapi \
- -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) $(GL_LIB_DEPS) -o $@
-
-
-glslcompiler.o: glslcompiler.c
- $(CC) -c $(INCLUDES) $(CFLAGS) glslcompiler.c -o $@
-
-
-clean:
- -rm -f *.o *~ $(PROGRAM)
diff --git a/src/mesa/drivers/glslcompiler/glslcompiler.c b/src/mesa/drivers/glslcompiler/glslcompiler.c
deleted file mode 100644
index 7259bf4c560..00000000000
--- a/src/mesa/drivers/glslcompiler/glslcompiler.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * 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 "main/imports.h"
-#include "main/context.h"
-#include "main/extensions.h"
-#include "main/framebuffer.h"
-#include "main/shaderapi.h"
-#include "main/shaderobj.h"
-#include "program/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_setup/swrast_setup.h"
-#include "vbo/vbo.h"
-
-
-static const char *Prog = "glslcompiler";
-
-
-struct options {
- GLboolean LineNumbers;
- GLboolean Link;
- gl_prog_print_mode Mode;
- const char *VertFile;
- const char *FragFile;
- const char *GeoFile;
- const char *OutputFile;
- GLboolean Params;
- struct gl_sl_pragmas Pragmas;
-};
-
-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_FALSE, GL_FALSE, /* RGB */
- 8, 8, 8, 8, /* color */
- 0, 0, /* z, stencil */
- 0, 0, 0, 0, 1); /* accum */
- buf = _mesa_create_framebuffer(vis);
-
- cc = calloc(1, sizeof(*cc));
- if (!vis || !buf || !cc) {
- if (vis)
- _mesa_destroy_visual(vis);
- if (buf)
- _mesa_destroy_framebuffer(buf);
- free(cc);
- 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_destroy_framebuffer(buf);
- _mesa_free_context_data(ctx);
- free(cc);
- return GL_FALSE;
- }
- TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
- _swsetup_Wakeup( ctx );
-
- /* Override the context's default pragma settings */
- ctx->Shader.DefaultPragmas = Options.Pragmas;
-
- _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);
-}
-
-
-static void
-CheckLink(GLuint v_shader, GLuint f_shader)
-{
- GLuint prog;
- GLint stat;
-
- prog = _mesa_CreateProgram();
-
- _mesa_AttachShader(prog, v_shader);
- _mesa_AttachShader(prog, f_shader);
-
- _mesa_LinkProgramARB(prog);
- _mesa_GetProgramiv(prog, GL_LINK_STATUS, &stat);
- if (!stat) {
- GLchar log[1000];
- GLsizei len;
- _mesa_GetProgramInfoLog(prog, 1000, &len, log);
- fprintf(stderr, "Linker error:\n%s\n", log);
- }
- else {
- fprintf(stderr, "Link success!\n");
- }
-}
-
-
-static void
-PrintShaderInstructions(GLuint shader, FILE *f)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
- struct gl_program *prog = sh->Program;
- _mesa_fprint_program_opt(stdout, prog, Options.Mode, Options.LineNumbers);
- if (Options.Params)
- _mesa_print_program_parameters(ctx, prog);
-}
-
-
-static GLuint
-CompileShader(const char *filename, GLenum type)
-{
- GLuint shader;
-
- assert(type == GL_FRAGMENT_SHADER ||
- type == GL_VERTEX_SHADER ||
- type == GL_GEOMETRY_SHADER_ARB);
-
- 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(" --gs FILE geometry shader input filename\n");
- printf(" --arb emit ARB-style instructions\n");
- printf(" --nv emit NV-style instructions\n");
- printf(" --link run linker\n");
- printf(" --debug force #pragma debug(on)\n");
- printf(" --nodebug force #pragma debug(off)\n");
- printf(" --opt force #pragma optimize(on)\n");
- printf(" --noopt force #pragma optimize(off)\n");
- printf(" --number, -n emit line numbers (if --arb or --nv)\n");
- printf(" --output, -o FILE output filename\n");
- printf(" --params also emit program parameter info\n");
- printf(" --help display this information\n");
-}
-
-
-static void
-ParseOptions(int argc, char *argv[])
-{
- int i;
-
- Options.LineNumbers = GL_FALSE;
- Options.Mode = PROG_PRINT_DEBUG;
- Options.VertFile = NULL;
- Options.FragFile = NULL;
- Options.GeoFile = NULL;
- Options.OutputFile = NULL;
- Options.Params = GL_FALSE;
- Options.Pragmas.IgnoreOptimize = GL_FALSE;
- Options.Pragmas.IgnoreDebug = GL_FALSE;
- Options.Pragmas.Debug = GL_FALSE;
- Options.Pragmas.Optimize = GL_TRUE;
-
- 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], "--gs") == 0) {
- Options.GeoFile = 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], "--link") == 0) {
- Options.Link = GL_TRUE;
- }
- else if (strcmp(argv[i], "--debug") == 0) {
- Options.Pragmas.IgnoreDebug = GL_TRUE;
- Options.Pragmas.Debug = GL_TRUE;
- }
- else if (strcmp(argv[i], "--nodebug") == 0) {
- Options.Pragmas.IgnoreDebug = GL_TRUE;
- Options.Pragmas.Debug = GL_FALSE;
- }
- else if (strcmp(argv[i], "--opt") == 0) {
- Options.Pragmas.IgnoreOptimize = GL_TRUE;
- Options.Pragmas.Optimize = GL_TRUE;
- }
- else if (strcmp(argv[i], "--noopt") == 0) {
- Options.Pragmas.IgnoreOptimize = GL_TRUE;
- Options.Pragmas.Optimize = GL_FALSE;
- }
- 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], "--params") == 0) {
- Options.Params = GL_TRUE;
- }
- else if (strcmp(argv[i], "--help") == 0) {
- Usage();
- exit(0);
- }
- else {
- printf("Unknown option: %s\n", argv[i]);
- Usage();
- exit(1);
- }
- }
-
- if (Options.Mode == PROG_PRINT_DEBUG) {
- /* always print line numbers when emitting debug-style output */
- Options.LineNumbers = GL_TRUE;
- }
-}
-
-
-int
-main(int argc, char *argv[])
-{
- GLuint v_shader = 0, f_shader = 0, g_shader = 0;
-
- ParseOptions(argc, argv);
-
- if (!CreateContext()) {
- fprintf(stderr, "%s: Failed to create compiler context\n", Prog);
- exit(1);
- }
-
- if (Options.VertFile) {
- v_shader = CompileShader(Options.VertFile, GL_VERTEX_SHADER);
- }
-
- if (Options.FragFile) {
- f_shader = CompileShader(Options.FragFile, GL_FRAGMENT_SHADER);
- }
-
- if (Options.GeoFile) {
- g_shader = CompileShader(Options.GeoFile, GL_GEOMETRY_SHADER_ARB);
- }
-
-
- if (v_shader || f_shader || g_shader) {
- if (Options.OutputFile) {
- FILE *f;
- fclose(stdout);
- /*stdout =*/ f = freopen(Options.OutputFile, "w", stdout);
- if (!f) {
- fprintf(stderr, "freopen error\n");
- }
- }
- if (stdout && v_shader) {
- PrintShaderInstructions(v_shader, stdout);
- }
- if (stdout && f_shader) {
- PrintShaderInstructions(f_shader, stdout);
- }
- if (stdout && g_shader) {
- PrintShaderInstructions(g_shader, stdout);
- }
- if (Options.OutputFile) {
- fclose(stdout);
- }
- }
-
- if (Options.Link) {
- if (!v_shader || !f_shader) {
- fprintf(stderr,
- "--link option requires both a vertex and fragment shader.\n");
- exit(1);
- }
-
- CheckLink(v_shader, f_shader);
- }
-
- return 0;
-}
diff --git a/src/mesa/drivers/osmesa/Makefile b/src/mesa/drivers/osmesa/Makefile
index c6b4a040851..39ab09af805 100644
--- a/src/mesa/drivers/osmesa/Makefile
+++ b/src/mesa/drivers/osmesa/Makefile
@@ -23,8 +23,7 @@ INCLUDE_DIRS = \
CORE_MESA = \
$(TOP)/src/mesa/libmesa.a \
$(TOP)/src/mapi/glapi/libglapi.a \
- $(TOP)/src/glsl/cl/libglslcl.a \
- $(TOP)/src/glsl/pp/libglslpp.a
+ $(TOP)/src/glsl/libglsl.a
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
@@ -37,9 +36,9 @@ default: $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME)
# sources. We can also build libOSMesa16/libOSMesa32 by setting
# -DCHAN_BITS=16/32.
$(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OBJECTS) $(CORE_MESA)
- $(MKLIB) -o $(OSMESA_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ $(MKLIB) -o $(OSMESA_LIB) -linker '$(CXX)' -ldflags '$(LDFLAGS)' \
-major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
- -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
+ -install $(TOP)/$(LIB_DIR) -cplusplus $(MKLIB_OPTIONS) \
-id $(INSTALL_LIB_DIR)/lib$(OSMESA_LIB).$(MESA_MAJOR).dylib \
$(OSMESA_LIB_DEPS) $(OBJECTS) $(CORE_MESA)
diff --git a/src/mesa/drivers/x11/Makefile b/src/mesa/drivers/x11/Makefile
index b5b0c1f11a8..f759da0a979 100644
--- a/src/mesa/drivers/x11/Makefile
+++ b/src/mesa/drivers/x11/Makefile
@@ -57,9 +57,10 @@ default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME)
$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) $(CORE_MESA)
- @ $(MKLIB) -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ @ $(MKLIB) -o $(GL_LIB) -linker '$(CXX)' -ldflags '$(LDFLAGS)' \
-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
- -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
+ -install $(TOP)/$(LIB_DIR) \
+ -cplusplus $(MKLIB_OPTIONS) \
-id $(INSTALL_LIB_DIR)/lib$(GL_LIB).$(GL_MAJOR).dylib \
$(GL_LIB_DEPS) $(OBJECTS) $(CORE_MESA)
diff --git a/src/mesa/main/accum.h b/src/mesa/main/accum.h
index 63740f07edc..c2b74b23cb4 100644
--- a/src/mesa/main/accum.h
+++ b/src/mesa/main/accum.h
@@ -55,6 +55,8 @@ _mesa_init_accum_dispatch(struct _glapi_table *disp);
#else /* FEATURE_accum */
+#include "main/compiler.h"
+
#define _MESA_INIT_ACCUM_FUNCTIONS(driver, impl) do { } while (0)
static INLINE void
diff --git a/src/mesa/main/attrib.h b/src/mesa/main/attrib.h
index 6b48a176630..83b28a65b77 100644
--- a/src/mesa/main/attrib.h
+++ b/src/mesa/main/attrib.h
@@ -48,6 +48,8 @@ _mesa_init_attrib_dispatch(struct _glapi_table *disp);
#else /* FEATURE_attrib_stack */
+#include "main/compiler.h"
+
static INLINE void
_mesa_PushClientAttrib( GLbitfield mask )
{
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 4e232b5731f..4797f29b4dc 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -590,7 +590,7 @@ bind_buffer_object(GLcontext *ctx, GLenum target, GLuint buffer)
bindTarget = get_buffer_target(ctx, target);
if (!bindTarget) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target 0x%x)");
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target 0x%x)", target);
return;
}
@@ -1553,27 +1553,27 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
if (readOffset < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyBuffserSubData(readOffset = %d)", readOffset);
+ "glCopyBuffserSubData(readOffset = %d)", (int) readOffset);
return;
}
if (writeOffset < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyBuffserSubData(writeOffset = %d)", writeOffset);
+ "glCopyBuffserSubData(writeOffset = %d)", (int) writeOffset);
return;
}
if (readOffset + size > src->Size) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyBuffserSubData(readOffset + size = %d)",
- readOffset, size);
+ (int) (readOffset + size));
return;
}
if (writeOffset + size > dst->Size) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glCopyBuffserSubData(writeOffset + size = %d)",
- writeOffset, size);
+ (int) (writeOffset + size));
return;
}
@@ -1617,13 +1617,13 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
if (offset < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glMapBufferRange(offset = %ld)", offset);
+ "glMapBufferRange(offset = %ld)", (long)offset);
return NULL;
}
if (length < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glMapBufferRange(length = %ld)", length);
+ "glMapBufferRange(length = %ld)", (long)length);
return NULL;
}
@@ -1708,13 +1708,13 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
if (offset < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glMapBufferRange(offset = %ld)", offset);
+ "glMapBufferRange(offset = %ld)", (long)offset);
return;
}
if (length < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glMapBufferRange(length = %ld)", length);
+ "glMapBufferRange(length = %ld)", (long)length);
return;
}
@@ -1746,8 +1746,8 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
if (offset + length > bufObj->Length) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glMapBufferRange(offset %ld + length %ld > mapped length %ld)",
- offset, length, bufObj->Length);
+ "glMapBufferRange(offset %ld + length %ld > mapped length %ld)",
+ (long)offset, (long)length, (long)bufObj->Length);
return;
}
diff --git a/src/mesa/main/colortab.h b/src/mesa/main/colortab.h
index 652fb582463..744f092d934 100644
--- a/src/mesa/main/colortab.h
+++ b/src/mesa/main/colortab.h
@@ -53,6 +53,8 @@ _mesa_init_colortable_dispatch(struct _glapi_table *disp);
#else /* FEATURE_colortable */
+#include "main/compiler.h"
+
#define _MESA_INIT_COLORTABLE_FUNCTIONS(driver, impl) do { } while (0)
static INLINE void GLAPIENTRY
diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index e0507ccf864..ded69c3106c 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -316,6 +316,11 @@ static INLINE GLuint CPU_TO_LE32(GLuint x)
#endif
#endif
+#if (__GNUC__ >= 3)
+#define PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a)))
+#else
+#define PRINTFLIKE(f, a)
+#endif
#ifndef NULL
#define NULL 0
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index b01fed1781e..8e34ec4124f 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -140,6 +140,10 @@
#include "sparc/sparc.h"
#endif
+#include "glsl_parser_extras.h"
+
+
+
#ifndef MESA_VERBOSE
int MESA_VERBOSE = 0;
#endif
@@ -339,16 +343,16 @@ _mesa_destroy_visual( GLvisual *vis )
static void
dummy_enum_func(void)
{
- gl_buffer_index bi;
- gl_colortable_index ci;
- gl_face_index fi;
- gl_frag_attrib fa;
- gl_frag_result fr;
- gl_texture_index ti;
- gl_vert_attrib va;
- gl_vert_result vr;
- gl_geom_attrib ga;
- gl_geom_result gr;
+ gl_buffer_index bi = BUFFER_FRONT_LEFT;
+ gl_colortable_index ci = COLORTABLE_PRECONVOLUTION;
+ gl_face_index fi = FACE_POS_X;
+ gl_frag_attrib fa = FRAG_ATTRIB_WPOS;
+ gl_frag_result fr = FRAG_RESULT_DEPTH;
+ gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX;
+ gl_vert_attrib va = VERT_ATTRIB_POS;
+ gl_vert_result vr = VERT_RESULT_HPOS;
+ gl_geom_attrib ga = GEOM_ATTRIB_POSITION;
+ gl_geom_result gr = GEOM_RESULT_POS;
(void) bi;
(void) ci;
@@ -434,6 +438,11 @@ one_time_init( GLcontext *ctx )
}
_glthread_UNLOCK_MUTEX(OneTimeLock);
+ /* Hopefully atexit() is widely available. If not, we may need some
+ * #ifdef tests here.
+ */
+ atexit(_mesa_destroy_shader_compiler);
+
dummy_enum_func();
}
@@ -1695,7 +1704,7 @@ _mesa_valid_to_render(GLcontext *ctx, const char *where)
/* using shaders */
if (!ctx->Shader.CurrentProgram->LinkStatus) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(shader not linked), where");
+ "%s(shader not linked)", where);
return GL_FALSE;
}
#if 0 /* not normally enabled */
diff --git a/src/mesa/main/convolve.h b/src/mesa/main/convolve.h
index 59492bc7c54..d1401885df4 100644
--- a/src/mesa/main/convolve.h
+++ b/src/mesa/main/convolve.h
@@ -70,6 +70,8 @@ _mesa_init_convolve_dispatch(struct _glapi_table *disp);
#else /* FEATURE_convolve */
+#include "main/compiler.h"
+
#define _MESA_INIT_CONVOLVE_FUNCTIONS(driver, impl) do { } while (0)
static INLINE void GLAPIENTRY
diff --git a/src/mesa/main/core.h b/src/mesa/main/core.h
new file mode 100644
index 00000000000..ea6e6bf1187
--- /dev/null
+++ b/src/mesa/main/core.h
@@ -0,0 +1,66 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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:
+ * Chia-I Wu <[email protected]>
+ */
+
+
+/**
+ * \file core.h
+ * The public header of core mesa.
+ *
+ * This file is the (only) public header of core mesa. It is supposed to be
+ * used by GLX, WGL, and GLSL. It is important that headers directly or
+ * indirectly included here do not perform feature tests (#if FEATURE_xxx).
+ */
+
+
+#ifndef CORE_H
+#define CORE_H
+
+
+#include "main/glheader.h"
+#include "main/compiler.h"
+#include "main/imports.h"
+#include "main/macros.h"
+
+#include "main/version.h" /* for MESA_VERSION_STRING */
+#include "main/context.h" /* for _mesa_share_state */
+#include "main/mtypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* for GLSL */
+#include "program/prog_parameter.h"
+#include "program/prog_uniform.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* CORE_H */
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 825073ca886..8a20a663632 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -36,7 +36,7 @@
struct gl_pixelstore_attrib;
struct gl_display_list;
-#if FEATURE_ARB_vertex_buffer_object
+/* GL_ARB_vertex_buffer_object */
/* Modifies GL_MAP_UNSYNCHRONIZED_BIT to allow driver to fail (return
* NULL) if buffer is unavailable for immediate mapping.
*
@@ -49,7 +49,6 @@ struct gl_display_list;
* respect the contents of already referenced data.
*/
#define MESA_MAP_NOWAIT_BIT 0x0040
-#endif
/**
@@ -595,6 +594,27 @@ struct dd_function_table {
/*@}*/
+ /**
+ * \name GLSL shader/program functions.
+ */
+ /*@{*/
+ /**
+ * Called when a shader is compiled.
+ *
+ * Note that not all shader objects get ShaderCompile called on
+ * them. Notably, the shaders containing builtin functions do not
+ * have CompileShader() called, so if lowering passes are done they
+ * need to also be performed in LinkShader().
+ */
+ GLboolean (*CompileShader)(GLcontext *ctx, struct gl_shader *shader);
+ /**
+ * Called when a shader program is linked.
+ *
+ * This gives drivers an opportunity to clone the IR and make their
+ * own transformations on it for the purposes of code generation.
+ */
+ GLboolean (*LinkShader)(GLcontext *ctx, struct gl_shader_program *shader);
+ /*@}*/
/**
* \name State-changing functions.
@@ -709,7 +729,6 @@ struct dd_function_table {
/**
* \name Vertex/pixel buffer object functions
*/
-#if FEATURE_ARB_vertex_buffer_object
/*@{*/
void (*BindBuffer)( GLcontext *ctx, GLenum target,
struct gl_buffer_object *obj );
@@ -753,12 +772,10 @@ struct dd_function_table {
GLboolean (*UnmapBuffer)( GLcontext *ctx, GLenum target,
struct gl_buffer_object *obj );
/*@}*/
-#endif
/**
* \name Functions for GL_APPLE_object_purgeable
*/
-#if FEATURE_APPLE_object_purgeable
/*@{*/
/* variations on ObjectPurgeable */
GLenum (*BufferObjectPurgeable)( GLcontext *ctx, struct gl_buffer_object *obj, GLenum option );
@@ -770,12 +787,10 @@ struct dd_function_table {
GLenum (*RenderObjectUnpurgeable)( GLcontext *ctx, struct gl_renderbuffer *obj, GLenum option );
GLenum (*TextureObjectUnpurgeable)( GLcontext *ctx, struct gl_texture_object *obj, GLenum option );
/*@}*/
-#endif
/**
- * \name Functions for GL_EXT_framebuffer_object
+ * \name Functions for GL_EXT_framebuffer_{object,blit}.
*/
-#if FEATURE_EXT_framebuffer_object
/*@{*/
struct gl_framebuffer * (*NewFramebuffer)(GLcontext *ctx, GLuint name);
struct gl_renderbuffer * (*NewRenderbuffer)(GLcontext *ctx, GLuint name);
@@ -794,13 +809,10 @@ struct dd_function_table {
void (*ValidateFramebuffer)(GLcontext *ctx,
struct gl_framebuffer *fb);
/*@}*/
-#endif
-#if FEATURE_EXT_framebuffer_blit
void (*BlitFramebuffer)(GLcontext *ctx,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
-#endif
/**
* \name Query objects
@@ -955,7 +967,6 @@ struct dd_function_table {
void (*EndCallList)( GLcontext *ctx );
-#if FEATURE_ARB_sync
/**
* \name GL_ARB_sync interfaces
*/
@@ -969,14 +980,12 @@ struct dd_function_table {
void (*ServerWaitSync)(GLcontext *, struct gl_sync_object *,
GLbitfield, GLuint64);
/*@}*/
-#endif
/** GL_NV_conditional_render */
void (*BeginConditionalRender)(GLcontext *ctx, struct gl_query_object *q,
GLenum mode);
void (*EndConditionalRender)(GLcontext *ctx, struct gl_query_object *q);
-#if FEATURE_OES_draw_texture
/**
* \name GL_OES_draw_texture interface
*/
@@ -984,9 +993,10 @@ struct dd_function_table {
void (*DrawTex)(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z,
GLfloat width, GLfloat height);
/*@}*/
-#endif
-#if FEATURE_OES_EGL_image
+ /**
+ * \name GL_OES_EGL_image interface
+ */
void (*EGLImageTargetTexture2D)(GLcontext *ctx, GLenum target,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage,
@@ -994,9 +1004,10 @@ struct dd_function_table {
void (*EGLImageTargetRenderbufferStorage)(GLcontext *ctx,
struct gl_renderbuffer *rb,
void *image_handle);
-#endif
-#if FEATURE_EXT_transform_feedback
+ /**
+ * \name GL_EXT_transform_feedback interface
+ */
struct gl_transform_feedback_object *
(*NewTransformFeedback)(GLcontext *ctx, GLuint name);
void (*DeleteTransformFeedback)(GLcontext *ctx,
@@ -1011,7 +1022,6 @@ struct dd_function_table {
struct gl_transform_feedback_object *obj);
void (*DrawTransformFeedback)(GLcontext *ctx, GLenum mode,
struct gl_transform_feedback_object *obj);
-#endif
};
@@ -1094,7 +1104,7 @@ typedef struct {
void (GLAPIENTRYP VertexAttrib3fvNV)( GLuint index, const GLfloat *v );
void (GLAPIENTRYP VertexAttrib4fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w );
void (GLAPIENTRYP VertexAttrib4fvNV)( GLuint index, const GLfloat *v );
-#if FEATURE_ARB_vertex_program
+ /* GL_ARB_vertex_program */
void (GLAPIENTRYP VertexAttrib1fARB)( GLuint index, GLfloat x );
void (GLAPIENTRYP VertexAttrib1fvARB)( GLuint index, const GLfloat *v );
void (GLAPIENTRYP VertexAttrib2fARB)( GLuint index, GLfloat x, GLfloat y );
@@ -1103,7 +1113,6 @@ typedef struct {
void (GLAPIENTRYP VertexAttrib3fvARB)( GLuint index, const GLfloat *v );
void (GLAPIENTRYP VertexAttrib4fARB)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w );
void (GLAPIENTRYP VertexAttrib4fvARB)( GLuint index, const GLfloat *v );
-#endif
/*@}*/
void (GLAPIENTRYP Rectf)( GLfloat, GLfloat, GLfloat, GLfloat );
diff --git a/src/mesa/main/depthstencil.c b/src/mesa/main/depthstencil.c
index 885e718a767..dbaa8416457 100644
--- a/src/mesa/main/depthstencil.c
+++ b/src/mesa/main/depthstencil.c
@@ -359,7 +359,7 @@ _mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx,
dsrb->Format == MESA_FORMAT_X8_Z24);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
- z24rb = _mesa_new_renderbuffer(ctx, 0);
+ z24rb = ctx->Driver.NewRenderbuffer(ctx, 0);
if (!z24rb)
return NULL;
@@ -645,7 +645,7 @@ _mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx, struct gl_renderbuffer *dsrb)
dsrb->Format == MESA_FORMAT_S8_Z24);
ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
- s8rb = _mesa_new_renderbuffer(ctx, 0);
+ s8rb = ctx->Driver.NewRenderbuffer(ctx, 0);
if (!s8rb)
return NULL;
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 727414d529f..5042e14a540 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -6070,8 +6070,15 @@ exec_GetAttribLocationARB(GLuint program, const GLchar *name)
FLUSH_VERTICES(ctx, 0);
return CALL_GetAttribLocationARB(ctx->Exec, (program, name));
}
-/* XXX more shader functions needed here */
+static GLint GLAPIENTRY
+exec_GetUniformLocationARB(GLuint program, const GLchar *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, 0);
+ return CALL_GetUniformLocationARB(ctx->Exec, (program, name));
+}
+/* XXX more shader functions needed here */
#if FEATURE_EXT_framebuffer_blit
@@ -9491,6 +9498,7 @@ _mesa_create_save_table(void)
/* ARB 30/31/32. GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */
SET_BindAttribLocationARB(table, exec_BindAttribLocationARB);
SET_GetAttribLocationARB(table, exec_GetAttribLocationARB);
+ SET_GetUniformLocationARB(table, exec_GetUniformLocationARB);
/* XXX additional functions need to be implemented here! */
/* 299. GL_EXT_blend_equation_separate */
diff --git a/src/mesa/main/dlist.h b/src/mesa/main/dlist.h
index f8255facc5e..d3f5c5cb4e5 100644
--- a/src/mesa/main/dlist.h
+++ b/src/mesa/main/dlist.h
@@ -81,6 +81,8 @@ extern void _mesa_init_dlist_dispatch(struct _glapi_table *disp);
#else /* FEATURE_dlist */
+#include "main/compiler.h"
+
#define _MESA_INIT_DLIST_FUNCTIONS(driver, impl) do { } while (0)
#define _MESA_INIT_DLIST_VTXFMT(vfmt, impl) do { } while (0)
diff --git a/src/mesa/main/es_generator.py b/src/mesa/main/es_generator.py
index 9a8f5a6f5e0..ecb34bb5cdf 100644
--- a/src/mesa/main/es_generator.py
+++ b/src/mesa/main/es_generator.py
@@ -215,6 +215,10 @@ extern void _mesa_error(void *ctx, GLenum error, const char *fmtString, ... );
#ifdef IN_DRI_DRIVER
#define _GLAPI_USE_REMAP_TABLE
#endif
+/* glapi uses GLAPIENTRY while GLES headers define GL_APIENTRY */
+#ifndef GLAPIENTRY
+#define GLAPIENTRY GL_APIENTRY
+#endif
#include "%sapi/glapi/glapitable.h"
#include "%sapi/glapi/glapioffsets.h"
#include "%sapi/glapi/glapidispatch.h"
@@ -603,13 +607,15 @@ for funcName in keys:
# are complete; remove the extra ", " at the front of each.
passthroughDeclarationString = passthroughDeclarationString[2:]
passthroughCallString = passthroughCallString[2:]
+ if not passthroughDeclarationString:
+ passthroughDeclarationString = "void"
# The Mesa functions are scattered across all the Mesa
# header files. The easiest way to manage declarations
# is to create them ourselves.
if funcName in allSpecials:
print "/* this function is special and is defined elsewhere */"
- print "extern %s GLAPIENTRY %s(%s);" % (returnType, passthroughFuncName, passthroughDeclarationString)
+ print "extern %s GL_APIENTRY %s(%s);" % (returnType, passthroughFuncName, passthroughDeclarationString)
# A function may be a core function (i.e. it exists in
# the core specification), a core addition (extension
@@ -662,7 +668,7 @@ for funcName in keys:
print
continue
- print "static %s %s(%s)" % (returnType, fullFuncName, declarationString)
+ print "static %s GL_APIENTRY %s(%s)" % (returnType, fullFuncName, declarationString)
print "{"
# Start printing our code pieces. Start with any local
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 19a1eebe6e9..c9862ca29e6 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -969,7 +969,7 @@ _mesa_get_extension_count(GLcontext *ctx)
if (0)
_mesa_debug(ctx, "%u of %d extensions enabled\n", ctx->Extensions.Count,
- Elements(default_extensions));
+ (int) Elements(default_extensions));
return ctx->Extensions.Count;
}
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 9a84e5a79cf..f80dd859936 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -93,6 +93,8 @@ delete_dummy_framebuffer(struct gl_framebuffer *fb)
void
_mesa_init_fbobjects(GLcontext *ctx)
{
+ _glthread_INIT_MUTEX(DummyFramebuffer.Mutex);
+ _glthread_INIT_MUTEX(DummyRenderbuffer.Mutex);
DummyFramebuffer.Delete = delete_dummy_framebuffer;
DummyRenderbuffer.Delete = delete_dummy_renderbuffer;
}
diff --git a/src/mesa/main/feedback.h b/src/mesa/main/feedback.h
index 3e8283ed23f..0762930044d 100644
--- a/src/mesa/main/feedback.h
+++ b/src/mesa/main/feedback.h
@@ -63,6 +63,8 @@ _mesa_init_feedback_dispatch(struct _glapi_table *disp);
#else /* FEATURE_feedback */
+#include "main/compiler.h"
+
#define _MESA_INIT_FEEDBACK_FUNCTIONS(driver, impl) do { } while (0)
static INLINE void
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index 90449cc04f0..112d7a00883 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -940,6 +940,18 @@ _mesa_is_format_compressed(gl_format format)
/**
+ * Determine if the given format represents a packed depth/stencil buffer.
+ */
+GLboolean
+_mesa_is_format_packed_depth_stencil(gl_format format)
+{
+ const struct gl_format_info *info = _mesa_get_format_info(format);
+
+ return info->BaseFormat == GL_DEPTH_STENCIL;
+}
+
+
+/**
* Return color encoding for given format.
* \return GL_LINEAR or GL_SRGB
*/
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index ad176caaa0f..e9467f486bf 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -190,6 +190,9 @@ _mesa_get_format_block_size(gl_format format, GLuint *bw, GLuint *bh);
extern GLboolean
_mesa_is_format_compressed(gl_format format);
+extern GLboolean
+_mesa_is_format_packed_depth_stencil(gl_format format);
+
extern GLenum
_mesa_get_format_color_encoding(gl_format format);
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index e0aac26f62b..a98c09cfbf3 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -611,7 +611,7 @@ _mesa_update_depth_buffer(GLcontext *ctx,
depthRb = fb->Attachment[attIndex].Renderbuffer;
- if (depthRb && depthRb->_BaseFormat == GL_DEPTH_STENCIL) {
+ if (depthRb && _mesa_is_format_packed_depth_stencil(depthRb->Format)) {
/* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */
if (!fb->_DepthBuffer
|| fb->_DepthBuffer->Wrapped != depthRb
@@ -652,7 +652,7 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
stencilRb = fb->Attachment[attIndex].Renderbuffer;
- if (stencilRb && stencilRb->_BaseFormat == GL_DEPTH_STENCIL) {
+ if (stencilRb && _mesa_is_format_packed_depth_stencil(stencilRb->Format)) {
/* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */
if (!fb->_StencilBuffer
|| fb->_StencilBuffer->Wrapped != stencilRb
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 632dadd1a5d..a3cb5ec168f 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -1661,16 +1661,22 @@ check_extra(GLcontext *ctx, const char *func, const struct value_desc *d)
for (e = d->extra; *e != EXTRA_END; e++)
switch (*e) {
case EXTRA_VERSION_30:
- if (version < 30)
- return GL_FALSE;
+ if (version >= 30) {
+ total++;
+ enabled++;
+ }
break;
case EXTRA_VERSION_31:
- if (version < 31)
- return GL_FALSE;
+ if (version >= 31) {
+ total++;
+ enabled++;
+ }
break;
case EXTRA_VERSION_32:
- if (version < 32)
- return GL_FALSE;
+ if (version >= 32) {
+ total++;
+ enabled++;
+ }
break;
case EXTRA_NEW_BUFFERS:
if (ctx->NewState & _NEW_BUFFERS)
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index 7961ad7e7dd..5e4fcd599c3 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -31,7 +31,7 @@
#include "extensions.h"
static const GLubyte *
-shading_laguage_version(GLcontext *ctx)
+shading_language_version(GLcontext *ctx)
{
switch (ctx->API) {
#if FEATURE_ARB_shading_language_100
@@ -98,7 +98,7 @@ _mesa_GetString( GLenum name )
return (const GLubyte *) ctx->Extensions.String;
#if FEATURE_ARB_shading_language_100 || FEATURE_ES2
case GL_SHADING_LANGUAGE_VERSION:
- return shading_laguage_version(ctx);
+ return shading_language_version(ctx);
#endif
#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program || \
FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 9c2ffd66d69..751f2065011 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -116,6 +116,42 @@ typedef union { GLfloat f; GLint i; } fi_type;
#endif
+/**
+ * \name Work-arounds for platforms that lack C99 math functions
+ */
+/*@{*/
+#if (!defined(_XOPEN_SOURCE) || (_XOPEN_SOURCE < 600)) && !defined(_ISOC99_SOURCE) \
+ && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)) \
+ && (!defined(_MSC_VER) || (_MSC_VER < 1400))
+#define acosf(f) ((float) acos(f))
+#define asinf(f) ((float) asin(f))
+#define atan2f(x,y) ((float) atan2(x,y))
+#define atanf(f) ((float) atan(f))
+#define cielf(f) ((float) ciel(f))
+#define cosf(f) ((float) cos(f))
+#define coshf(f) ((float) cosh(f))
+#define expf(f) ((float) exp(f))
+#define exp2f(f) ((float) exp2(f))
+#define floorf(f) ((float) floor(f))
+#define logf(f) ((float) log(f))
+#define log2f(f) ((float) log2(f))
+#define powf(x,y) ((float) pow(x,y))
+#define sinf(f) ((float) sin(f))
+#define sinhf(f) ((float) sinh(f))
+#define sqrtf(f) ((float) sqrt(f))
+#define tanf(f) ((float) tan(f))
+#define tanhf(f) ((float) tanh(f))
+#endif
+
+#if defined(_MSC_VER)
+static INLINE float truncf(float x) { return x < 0.0f ? ceilf(x) : floorf(x); }
+static INLINE float exp2f(float x) { return powf(2.0f, x); }
+static INLINE float log2f(float x) { return logf(x) * 1.442695041f; }
+static INLINE int isblank(int ch) { return ch == ' ' || ch == '\t'; }
+#define strtoll(p, e, b) _strtoi64(p, e, b)
+#endif
+/*@}*/
+
/***
*** LOG2: Log base 2 of float
***/
@@ -530,19 +566,25 @@ extern unsigned int
_mesa_str_checksum(const char *str);
extern int
-_mesa_snprintf( char *str, size_t size, const char *fmt, ... );
+_mesa_snprintf( char *str, size_t size, const char *fmt, ... ) PRINTFLIKE(3, 4);
extern void
-_mesa_warning( __GLcontext *gc, const char *fmtString, ... );
+_mesa_warning( __GLcontext *gc, const char *fmtString, ... ) PRINTFLIKE(2, 3);
extern void
-_mesa_problem( const __GLcontext *ctx, const char *fmtString, ... );
+_mesa_problem( const __GLcontext *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
extern void
-_mesa_error( __GLcontext *ctx, GLenum error, const char *fmtString, ... );
+_mesa_error( __GLcontext *ctx, GLenum error, const char *fmtString, ... ) PRINTFLIKE(3, 4);
extern void
-_mesa_debug( const __GLcontext *ctx, const char *fmtString, ... );
+_mesa_debug( const __GLcontext *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3);
+
+
+#if defined(_MSC_VER) && !defined(snprintf)
+#define snprintf _snprintf
+#endif
+
#ifdef __cplusplus
}
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index c0c29f78893..678d17a2a36 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -1005,21 +1005,28 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
const GLint dstRowBytes = bpt * dstRowStride;
const GLubyte *srcA, *srcB;
GLubyte *dst;
- GLint row;
+ GLint row, srcRowStep;
/* Compute src and dst pointers, skipping any border */
srcA = srcPtr + border * ((srcWidth + 1) * bpt);
- if (srcHeight > 1)
+ if (srcHeight > 1 && srcHeight > dstHeight) {
+ /* sample from two source rows */
srcB = srcA + srcRowBytes;
- else
+ srcRowStep = 2;
+ }
+ else {
+ /* sample from one source row */
srcB = srcA;
+ srcRowStep = 1;
+ }
+
dst = dstPtr + border * ((dstWidth + 1) * bpt);
for (row = 0; row < dstHeightNB; row++) {
do_row(datatype, comps, srcWidthNB, srcA, srcB,
dstWidthNB, dst);
- srcA += 2 * srcRowBytes;
- srcB += 2 * srcRowBytes;
+ srcA += srcRowStep * srcRowBytes;
+ srcB += srcRowStep * srcRowBytes;
dst += dstRowBytes;
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 8d92892ad7d..d44eff69cce 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1632,10 +1632,9 @@ struct gl_array_attrib
GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */
-#if FEATURE_ARB_vertex_buffer_object
+ /* GL_ARB_vertex_buffer_object */
struct gl_buffer_object *ArrayBufferObj;
struct gl_buffer_object *ElementArrayBufferObj;
-#endif
};
@@ -2084,6 +2083,15 @@ struct gl_shader
struct gl_program *Program; /**< Post-compile assembly code */
GLchar *InfoLog;
struct gl_sl_pragmas Pragmas;
+
+ unsigned Version; /**< GLSL version used for linking */
+
+ struct exec_list *ir;
+ struct glsl_symbol_table *symbols;
+
+ /** Shaders containing built-in functions that are used for linking. */
+ struct gl_shader *builtins_to_link[16];
+ unsigned num_builtins_to_link;
};
@@ -2129,6 +2137,16 @@ struct gl_shader_program
GLboolean Validated;
GLboolean _Used; /**< Ever used for drawing? */
GLchar *InfoLog;
+
+ unsigned Version; /**< GLSL version used for linking */
+
+ /**
+ * Per-stage shaders resulting from the first stage of linking.
+ */
+ /*@{*/
+ GLuint _NumLinkedShaders;
+ struct gl_shader *_LinkedShaders[2];
+ /*@}*/
};
@@ -2154,6 +2172,11 @@ struct gl_shader_state
GLboolean EmitCondCodes; /**< Use condition codes? */
GLboolean EmitComments; /**< Annotated instructions */
GLboolean EmitNVTempInitialization; /**< 0-fill NV temp registers */
+ /**
+ * Attempts to flatten all ir_if (OPCODE_IF) for GPUs that can't
+ * support control flow.
+ */
+ GLboolean EmitNoIfs;
void *MemPool;
GLbitfield Flags; /**< Mask of GLSL_x flags */
struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */
@@ -2240,39 +2263,26 @@ struct gl_shared_state
*/
/*@{*/
struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
-#if FEATURE_ARB_vertex_program
struct gl_vertex_program *DefaultVertexProgram;
-#endif
-#if FEATURE_ARB_fragment_program
struct gl_fragment_program *DefaultFragmentProgram;
-#endif
-#if FEATURE_ARB_geometry_shader4
struct gl_geometry_program *DefaultGeometryProgram;
-#endif
/*@}*/
-#if FEATURE_ATI_fragment_shader
+ /* GL_ATI_fragment_shader */
struct _mesa_HashTable *ATIShaders;
struct ati_fragment_shader *DefaultFragmentShader;
-#endif
-#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
struct _mesa_HashTable *BufferObjects;
-#endif
-#if FEATURE_ARB_shader_objects
/** Table of both gl_shader and gl_shader_program objects */
struct _mesa_HashTable *ShaderObjects;
-#endif
-#if FEATURE_EXT_framebuffer_object
+ /* GL_EXT_framebuffer_object */
struct _mesa_HashTable *RenderBuffers;
struct _mesa_HashTable *FrameBuffers;
-#endif
-#if FEATURE_ARB_sync
+ /* GL_ARB_sync */
struct simple_node SyncObjects;
-#endif
void *DriverData; /**< Device driver shared state */
};
@@ -2507,14 +2517,13 @@ struct gl_program_constants
GLuint MaxNativeParameters;
/* For shaders */
GLuint MaxUniformComponents;
-#if FEATURE_ARB_geometry_shader4
+ /* GL_ARB_geometry_shader4 */
GLuint MaxGeometryTextureImageUnits;
GLuint MaxGeometryVaryingComponents;
GLuint MaxVertexVaryingComponents;
GLuint MaxGeometryUniformComponents;
GLuint MaxGeometryOutputVertices;
GLuint MaxGeometryTotalOutputComponents;
-#endif
};
@@ -2762,12 +2771,8 @@ struct gl_extensions
GLboolean SGIS_texture_lod;
GLboolean TDFX_texture_compression_FXT1;
GLboolean S3_s3tc;
-#if FEATURE_OES_EGL_image
GLboolean OES_EGL_image;
-#endif
-#if FEATURE_OES_draw_texture
GLboolean OES_draw_texture;
-#endif /* FEATURE_OES_draw_texture */
/** The extension string */
const GLubyte *String;
/** Number of supported extensions */
@@ -3208,9 +3213,8 @@ struct __GLcontextRec
struct gl_meta_state *Meta; /**< for "meta" operations */
-#if FEATURE_EXT_framebuffer_object
+ /* GL_EXT_framebuffer_object */
struct gl_renderbuffer *CurrentRenderbuffer;
-#endif
GLenum ErrorValue; /**< Last error code */
diff --git a/src/mesa/main/querymatrix.c b/src/mesa/main/querymatrix.c
index 32aaa79f7fb..36236eb9a75 100644
--- a/src/mesa/main/querymatrix.c
+++ b/src/mesa/main/querymatrix.c
@@ -72,7 +72,8 @@ fpclassify(double x)
#elif defined(__APPLE__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
- (defined(__sun) && defined(__C99FEATURES__)) || defined(__MINGW32__)
+ (defined(__sun) && defined(__C99FEATURES__)) || defined(__MINGW32__) || \
+ (defined(__sun) && defined(__GNUC__))
/* fpclassify is available. */
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 9cb2391035d..cc350c93b97 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -46,8 +46,7 @@
#include "program/program.h"
#include "program/prog_parameter.h"
#include "program/prog_uniform.h"
-#include "slang/slang_compile.h"
-#include "slang/slang_link.h"
+#include "talloc.h"
/** Define this to enable shader substitution (see below) */
@@ -99,6 +98,7 @@ _mesa_init_shader_state(GLcontext *ctx)
ctx->Shader.EmitContReturn = GL_TRUE;
ctx->Shader.EmitCondCodes = GL_FALSE;
ctx->Shader.EmitComments = GL_FALSE;
+ ctx->Shader.EmitNoIfs = GL_FALSE;
ctx->Shader.Flags = get_shader_flags();
/* Default pragma settings */
@@ -800,7 +800,7 @@ compile_shader(GLcontext *ctx, GLuint shaderObj)
/* this call will set the sh->CompileStatus field to indicate if
* compilation was successful.
*/
- (void) _slang_compile(ctx, sh);
+ _mesa_glsl_compile_shader(ctx, sh);
}
@@ -826,7 +826,7 @@ link_program(GLcontext *ctx, GLuint program)
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
- _slang_link(ctx, program, shProg);
+ _mesa_glsl_link_shader(ctx, shProg);
/* debug code */
if (0) {
@@ -1051,9 +1051,9 @@ validate_program(GLcontext *ctx, GLuint program)
if (!shProg->Validated) {
/* update info log */
if (shProg->InfoLog) {
- free(shProg->InfoLog);
+ talloc_free(shProg->InfoLog);
}
- shProg->InfoLog = _mesa_strdup(errMsg);
+ shProg->InfoLog = talloc_strdup(shProg, errMsg);
}
}
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 14bbb2e4bc3..59198d788bd 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -36,7 +36,7 @@
#include "program/program.h"
#include "program/prog_parameter.h"
#include "program/prog_uniform.h"
-
+#include "talloc.h"
/**********************************************************************/
/*** Shader object functions ***/
@@ -87,22 +87,27 @@ _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
}
}
+void
+_mesa_init_shader(GLcontext *ctx, struct gl_shader *shader)
+{
+ shader->RefCount = 1;
+}
/**
* Allocate a new gl_shader object, initialize it.
* Called via ctx->Driver.NewShader()
*/
-static struct gl_shader *
+struct gl_shader *
_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
{
struct gl_shader *shader;
assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER ||
type == GL_GEOMETRY_SHADER_ARB);
- shader = CALLOC_STRUCT(gl_shader);
+ shader = talloc_zero(NULL, struct gl_shader);
if (shader) {
shader->Type = type;
shader->Name = name;
- shader->RefCount = 1;
+ _mesa_init_shader(ctx, shader);
}
return shader;
}
@@ -113,14 +118,12 @@ _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
* Called via ctx->Driver.DeleteShader().
*/
static void
-__mesa_delete_shader(GLcontext *ctx, struct gl_shader *sh)
+_mesa_delete_shader(GLcontext *ctx, struct gl_shader *sh)
{
if (sh->Source)
free((void *) sh->Source);
- if (sh->InfoLog)
- free(sh->InfoLog);
_mesa_reference_program(ctx, &sh->Program, NULL);
- free(sh);
+ talloc_free(sh);
}
@@ -226,6 +229,18 @@ _mesa_reference_shader_program(GLcontext *ctx,
}
}
+void
+_mesa_init_shader_program(GLcontext *ctx, struct gl_shader_program *prog)
+{
+ prog->Type = GL_SHADER_PROGRAM_MESA;
+ prog->RefCount = 1;
+ prog->Attributes = _mesa_new_parameter_list();
+#if FEATURE_ARB_geometry_shader4
+ prog->Geom.VerticesOut = 0;
+ prog->Geom.InputType = GL_TRIANGLES;
+ prog->Geom.OutputType = GL_TRIANGLE_STRIP;
+#endif
+}
/**
* Allocate a new gl_shader_program object, initialize it.
@@ -235,17 +250,10 @@ static struct gl_shader_program *
_mesa_new_shader_program(GLcontext *ctx, GLuint name)
{
struct gl_shader_program *shProg;
- shProg = CALLOC_STRUCT(gl_shader_program);
+ shProg = talloc_zero(NULL, struct gl_shader_program);
if (shProg) {
- shProg->Type = GL_SHADER_PROGRAM_MESA;
shProg->Name = name;
- shProg->RefCount = 1;
- shProg->Attributes = _mesa_new_parameter_list();
-#if FEATURE_ARB_geometry_shader4
- shProg->Geom.VerticesOut = 0;
- shProg->Geom.InputType = GL_TRIANGLES;
- shProg->Geom.OutputType = GL_TRIANGLE_STRIP;
-#endif
+ _mesa_init_shader_program(ctx, shProg);
}
return shProg;
}
@@ -305,7 +313,7 @@ _mesa_free_shader_program_data(GLcontext *ctx,
}
if (shProg->InfoLog) {
- free(shProg->InfoLog);
+ talloc_free(shProg->InfoLog);
shProg->InfoLog = NULL;
}
@@ -316,6 +324,12 @@ _mesa_free_shader_program_data(GLcontext *ctx,
free(shProg->TransformFeedback.VaryingNames);
shProg->TransformFeedback.VaryingNames = NULL;
shProg->TransformFeedback.NumVarying = 0;
+
+
+ for (i = 0; i < shProg->_NumLinkedShaders; i++) {
+ ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[i]);
+ }
+ shProg->_NumLinkedShaders = 0;
}
@@ -324,11 +338,11 @@ _mesa_free_shader_program_data(GLcontext *ctx,
* Called via ctx->Driver.DeleteShaderProgram().
*/
static void
-__mesa_delete_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
+_mesa_delete_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
{
_mesa_free_shader_program_data(ctx, shProg);
- free(shProg);
+ talloc_free(shProg);
}
@@ -386,7 +400,9 @@ void
_mesa_init_shader_object_functions(struct dd_function_table *driver)
{
driver->NewShader = _mesa_new_shader;
- driver->DeleteShader = __mesa_delete_shader;
+ driver->DeleteShader = _mesa_delete_shader;
driver->NewShaderProgram = _mesa_new_shader_program;
- driver->DeleteShaderProgram = __mesa_delete_shader_program;
+ driver->DeleteShaderProgram = _mesa_delete_shader_program;
+ driver->CompileShader = _mesa_ir_compile_shader;
+ driver->LinkShader = _mesa_ir_link_shader;
}
diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h
index d6b37b45963..48000463752 100644
--- a/src/mesa/main/shaderobj.h
+++ b/src/mesa/main/shaderobj.h
@@ -27,8 +27,22 @@
#define SHADEROBJ_H
-#include "glheader.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "program/ir_to_mesa.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * Internal functions
+ */
+
+extern void
+_mesa_init_shader_state(GLcontext * ctx);
+
+extern void
+_mesa_free_shader_state(GLcontext *ctx);
extern void
@@ -47,6 +61,14 @@ extern void
_mesa_reference_shader_program(GLcontext *ctx,
struct gl_shader_program **ptr,
struct gl_shader_program *shProg);
+extern void
+_mesa_init_shader(GLcontext *ctx, struct gl_shader *shader);
+
+extern struct gl_shader *
+_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
+
+extern void
+_mesa_init_shader_program(GLcontext *ctx, struct gl_shader_program *prog);
extern struct gl_shader_program *
_mesa_lookup_shader_program(GLcontext *ctx, GLuint name);
@@ -74,5 +96,8 @@ _mesa_init_shader_state(GLcontext *ctx);
extern void
_mesa_free_shader_state(GLcontext *ctx);
+#ifdef __cplusplus
+}
+#endif
#endif /* SHADEROBJ_H */
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index cbe004518a0..ea7e503cf3b 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -288,6 +288,10 @@ free_shared_state(GLcontext *ctx, struct gl_shared_state *shared)
{
GLuint i;
+ /* Free the dummy/fallback texture object */
+ if (shared->FallbackTex)
+ ctx->Driver.DeleteTexture(ctx, shared->FallbackTex);
+
/*
* Free display lists
*/
diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c
index c70792cab61..8e059802625 100644
--- a/src/mesa/main/texcompress_s3tc.c
+++ b/src/mesa/main/texcompress_s3tc.c
@@ -149,7 +149,6 @@ _mesa_init_texture_s3tc( GLcontext *ctx )
}
if (dxtlibhandle) {
ctx->Mesa_DXTn = GL_TRUE;
- _mesa_warning(ctx, "software DXTn compression/decompression available");
}
#else
(void) ctx;
diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c
index f86f1911d1d..5c8c1fd225f 100644
--- a/src/mesa/main/transformfeedback.c
+++ b/src/mesa/main/transformfeedback.c
@@ -455,14 +455,14 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
if ((size <= 0) || (size & 0x3)) {
/* must be positive and multiple of four */
- _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size%d)", size);
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size%d)", (int) size);
return;
}
if (offset & 0x3) {
/* must be multiple of four */
_mesa_error(ctx, GL_INVALID_VALUE,
- "glBindBufferRange(offset=%d)", offset);
+ "glBindBufferRange(offset=%d)", (int) offset);
return;
}
@@ -475,7 +475,8 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
if (offset + size >= bufObj->Size) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glBindBufferRange(offset + size > buffer size)", size);
+ "glBindBufferRange(offset + size %d > buffer size %d)",
+ (int) (offset + size), (int) (bufObj->Size));
return;
}
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index d68a7768df5..a5d7da51f07 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -454,17 +454,12 @@ _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
* The return value will encode two values, the uniform location and an
* offset (used for arrays, structs).
*/
-static GLint
-_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
+GLint
+_mesa_get_uniform_location(GLcontext *ctx, struct gl_shader_program *shProg,
+ const GLchar *name)
{
GLint offset = 0, location = -1;
- struct gl_shader_program *shProg =
- _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
-
- if (!shProg)
- return -1;
-
if (shProg->LinkStatus == GL_FALSE) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
return -1;
@@ -751,11 +746,11 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
/**
* Called via glUniform*() functions.
*/
-static void
-_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
+void
+_mesa_uniform(GLcontext *ctx, struct gl_shader_program *shProg,
+ GLint location, GLsizei count,
const GLvoid *values, GLenum type)
{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
struct gl_uniform *uniform;
GLint elems, offset;
@@ -923,12 +918,12 @@ set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
* Called by glUniformMatrix*() functions.
* Note: cols=2, rows=4 ==> array[2] of vec4
*/
-static void
-_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
+void
+_mesa_uniform_matrix(GLcontext *ctx, struct gl_shader_program *shProg,
+ GLint cols, GLint rows,
GLint location, GLsizei count,
GLboolean transpose, const GLfloat *values)
{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
struct gl_uniform *uniform;
GLint offset;
@@ -999,7 +994,7 @@ void GLAPIENTRY
_mesa_Uniform1fARB(GLint location, GLfloat v0)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, 1, &v0, GL_FLOAT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, &v0, GL_FLOAT);
}
void GLAPIENTRY
@@ -1009,7 +1004,7 @@ _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
GLfloat v[2];
v[0] = v0;
v[1] = v1;
- _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_FLOAT_VEC2);
}
void GLAPIENTRY
@@ -1020,7 +1015,7 @@ _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
v[0] = v0;
v[1] = v1;
v[2] = v2;
- _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_FLOAT_VEC3);
}
void GLAPIENTRY
@@ -1033,14 +1028,14 @@ _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
v[1] = v1;
v[2] = v2;
v[3] = v3;
- _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_FLOAT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1iARB(GLint location, GLint v0)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, 1, &v0, GL_INT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, &v0, GL_INT);
}
void GLAPIENTRY
@@ -1050,7 +1045,7 @@ _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
GLint v[2];
v[0] = v0;
v[1] = v1;
- _mesa_uniform(ctx, location, 1, v, GL_INT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_INT_VEC2);
}
void GLAPIENTRY
@@ -1061,7 +1056,7 @@ _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
v[0] = v0;
v[1] = v1;
v[2] = v2;
- _mesa_uniform(ctx, location, 1, v, GL_INT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_INT_VEC3);
}
void GLAPIENTRY
@@ -1073,63 +1068,63 @@ _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
v[1] = v1;
v[2] = v2;
v[3] = v3;
- _mesa_uniform(ctx, location, 1, v, GL_INT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_INT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_FLOAT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_FLOAT);
}
void GLAPIENTRY
_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_FLOAT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_FLOAT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_FLOAT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_INT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_INT);
}
void GLAPIENTRY
_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_INT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_INT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_INT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_INT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_INT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_INT_VEC4);
}
@@ -1138,7 +1133,7 @@ void GLAPIENTRY
_mesa_Uniform1ui(GLint location, GLuint v0)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, &v0, GL_UNSIGNED_INT);
}
void GLAPIENTRY
@@ -1148,7 +1143,7 @@ _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
GLuint v[2];
v[0] = v0;
v[1] = v1;
- _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
}
void GLAPIENTRY
@@ -1159,7 +1154,7 @@ _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
v[0] = v0;
v[1] = v1;
v[2] = v2;
- _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
}
void GLAPIENTRY
@@ -1171,35 +1166,35 @@ _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
v[1] = v1;
v[2] = v2;
v[3] = v3;
- _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_UNSIGNED_INT);
}
void GLAPIENTRY
_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
}
@@ -1209,7 +1204,8 @@ _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 2, 2, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 2, 2, location, count, transpose, value);
}
void GLAPIENTRY
@@ -1217,7 +1213,8 @@ _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 3, 3, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 3, 3, location, count, transpose, value);
}
void GLAPIENTRY
@@ -1225,7 +1222,8 @@ _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 4, 4, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 4, 4, location, count, transpose, value);
}
@@ -1237,7 +1235,8 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 2, 3, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 2, 3, location, count, transpose, value);
}
void GLAPIENTRY
@@ -1245,7 +1244,8 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 3, 2, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 3, 2, location, count, transpose, value);
}
void GLAPIENTRY
@@ -1253,7 +1253,8 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 2, 4, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 2, 4, location, count, transpose, value);
}
void GLAPIENTRY
@@ -1261,7 +1262,8 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 4, 2, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 4, 2, location, count, transpose, value);
}
void GLAPIENTRY
@@ -1269,7 +1271,8 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 3, 4, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 3, 4, location, count, transpose, value);
}
void GLAPIENTRY
@@ -1277,7 +1280,8 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 4, 3, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 4, 3, location, count, transpose, value);
}
@@ -1300,8 +1304,16 @@ _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
{
+ struct gl_shader_program *shProg;
+
GET_CURRENT_CONTEXT(ctx);
- return _mesa_get_uniform_location(ctx, programObj, name);
+
+ shProg = _mesa_lookup_shader_program_err(ctx, programObj,
+ "glGetUniformLocation");
+ if (!shProg)
+ return -1;
+
+ return _mesa_get_uniform_location(ctx, shProg, name);
}
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index ef98fe16bb1..f823c614447 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -150,7 +150,20 @@ _mesa_GetUniformivARB(GLhandleARB, GLint, GLint *);
extern GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB, const GLcharARB *);
-
+GLint
+_mesa_get_uniform_location(GLcontext *ctx, struct gl_shader_program *shProg,
+ const GLchar *name);
+
+void
+_mesa_uniform(GLcontext *ctx, struct gl_shader_program *shader_program,
+ GLint location, GLsizei count,
+ const GLvoid *values, GLenum type);
+
+void
+_mesa_uniform_matrix(GLcontext *ctx, struct gl_shader_program *shProg,
+ GLint cols, GLint rows,
+ GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *values);
extern void
_mesa_update_shader_textures_used(struct gl_program *prog);
diff --git a/src/mesa/program/hash_table.c b/src/mesa/program/hash_table.c
index fa6ba2bfdfc..f7ef366c1a0 100644
--- a/src/mesa/program/hash_table.c
+++ b/src/mesa/program/hash_table.c
@@ -142,6 +142,23 @@ hash_table_insert(struct hash_table *ht, void *data, const void *key)
insert_at_head(& ht->buckets[bucket], & node->link);
}
+void
+hash_table_remove(struct hash_table *ht, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct node *node;
+
+ foreach(node, & ht->buckets[bucket]) {
+ struct hash_node *hn = (struct hash_node *) node;
+
+ if ((*ht->compare)(hn->key, key) == 0) {
+ remove_from_list(node);
+ free(node);
+ return;
+ }
+ }
+}
unsigned
hash_table_string_hash(const void *key)
@@ -157,3 +174,17 @@ hash_table_string_hash(const void *key)
return hash;
}
+
+
+unsigned
+hash_table_pointer_hash(const void *key)
+{
+ return (unsigned)((uintptr_t) key / sizeof(void *));
+}
+
+
+int
+hash_table_pointer_compare(const void *key1, const void *key2)
+{
+ return key1 == key2 ? 0 : 1;
+}
diff --git a/src/mesa/program/hash_table.h b/src/mesa/program/hash_table.h
index e750906f961..f1c4fdcd1fa 100644
--- a/src/mesa/program/hash_table.h
+++ b/src/mesa/program/hash_table.h
@@ -36,6 +36,10 @@ struct hash_table;
typedef unsigned (*hash_func_t)(const void *key);
typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* Hash table constructor
*
@@ -88,6 +92,10 @@ extern void *hash_table_find(struct hash_table *ht, const void *key);
extern void hash_table_insert(struct hash_table *ht, void *data,
const void *key);
+/**
+ * Remove a specific element from a hash table.
+ */
+extern void hash_table_remove(struct hash_table *ht, const void *key);
/**
* Compute hash value of a string
@@ -112,4 +120,31 @@ extern unsigned hash_table_string_hash(const void *key);
*/
#define hash_table_string_compare ((hash_compare_func_t) strcmp)
+
+/**
+ * Compute hash value of a pointer
+ *
+ * \param key Pointer to be used as a hash key
+ *
+ * \note
+ * The memory pointed to by \c key is \b never accessed. The value of \c key
+ * itself is used as the hash key
+ *
+ * \sa hash_table_pointer_compare
+ */
+unsigned
+hash_table_pointer_hash(const void *key);
+
+
+/**
+ * Compare two pointers used as keys
+ *
+ * \sa hash_table_pointer_hash
+ */
+int
+hash_table_pointer_compare(const void *key1, const void *key2);
+
+#ifdef __cplusplus
+}
+#endif
#endif /* HASH_TABLE_H */
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
new file mode 100644
index 00000000000..f0e14b8ece3
--- /dev/null
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -0,0 +1,2796 @@
+/*
+ * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
+ * Copyright © 2010 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 ir_to_mesa.cpp
+ *
+ * Translates the IR to ARB_fragment_program text if possible,
+ * printing the result
+ */
+
+#include <stdio.h>
+#include "main/compiler.h"
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_print_visitor.h"
+#include "ir_expression_flattening.h"
+#include "glsl_types.h"
+#include "glsl_parser_extras.h"
+#include "../glsl/program.h"
+#include "ir_optimization.h"
+#include "ast.h"
+
+extern "C" {
+#include "main/mtypes.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "main/uniforms.h"
+#include "program/hash_table.h"
+#include "program/prog_instruction.h"
+#include "program/prog_optimize.h"
+#include "program/prog_print.h"
+#include "program/program.h"
+#include "program/prog_uniform.h"
+#include "program/prog_parameter.h"
+}
+
+static int swizzle_for_size(int size);
+
+/**
+ * This struct is a corresponding struct to Mesa prog_src_register, with
+ * wider fields.
+ */
+typedef struct ir_to_mesa_src_reg {
+ ir_to_mesa_src_reg(int file, int index, const glsl_type *type)
+ {
+ this->file = file;
+ this->index = index;
+ if (type && (type->is_scalar() || type->is_vector() || type->is_matrix()))
+ this->swizzle = swizzle_for_size(type->vector_elements);
+ else
+ this->swizzle = SWIZZLE_XYZW;
+ this->negate = 0;
+ this->reladdr = NULL;
+ }
+
+ ir_to_mesa_src_reg()
+ {
+ this->file = PROGRAM_UNDEFINED;
+ this->index = 0;
+ this->swizzle = 0;
+ this->negate = 0;
+ this->reladdr = NULL;
+ }
+
+ int file; /**< PROGRAM_* from Mesa */
+ int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+ GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
+ int negate; /**< NEGATE_XYZW mask from mesa */
+ /** Register index should be offset by the integer in this reg. */
+ ir_to_mesa_src_reg *reladdr;
+} ir_to_mesa_src_reg;
+
+typedef struct ir_to_mesa_dst_reg {
+ int file; /**< PROGRAM_* from Mesa */
+ int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+ int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
+ GLuint cond_mask:4;
+ /** Register index should be offset by the integer in this reg. */
+ ir_to_mesa_src_reg *reladdr;
+} ir_to_mesa_dst_reg;
+
+extern ir_to_mesa_src_reg ir_to_mesa_undef;
+
+class ir_to_mesa_instruction : public exec_node {
+public:
+ /* Callers of this talloc-based new need not call delete. It's
+ * easier to just talloc_free 'ctx' (or any of its ancestors). */
+ static void* operator new(size_t size, void *ctx)
+ {
+ void *node;
+
+ node = talloc_zero_size(ctx, size);
+ assert(node != NULL);
+
+ return node;
+ }
+
+ enum prog_opcode op;
+ ir_to_mesa_dst_reg dst_reg;
+ ir_to_mesa_src_reg src_reg[3];
+ /** Pointer to the ir source this tree came from for debugging */
+ ir_instruction *ir;
+ GLboolean cond_update;
+ int sampler; /**< sampler index */
+ int tex_target; /**< One of TEXTURE_*_INDEX */
+ GLboolean tex_shadow;
+
+ class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */
+};
+
+class variable_storage : public exec_node {
+public:
+ variable_storage(ir_variable *var, int file, int index)
+ : file(file), index(index), var(var)
+ {
+ /* empty */
+ }
+
+ int file;
+ int index;
+ ir_variable *var; /* variable that maps to this, if any */
+};
+
+class function_entry : public exec_node {
+public:
+ ir_function_signature *sig;
+
+ /**
+ * identifier of this function signature used by the program.
+ *
+ * At the point that Mesa instructions for function calls are
+ * generated, we don't know the address of the first instruction of
+ * the function body. So we make the BranchTarget that is called a
+ * small integer and rewrite them during set_branchtargets().
+ */
+ int sig_id;
+
+ /**
+ * Pointer to first instruction of the function body.
+ *
+ * Set during function body emits after main() is processed.
+ */
+ ir_to_mesa_instruction *bgn_inst;
+
+ /**
+ * Index of the first instruction of the function body in actual
+ * Mesa IR.
+ *
+ * Set after convertion from ir_to_mesa_instruction to prog_instruction.
+ */
+ int inst;
+
+ /** Storage for the return value. */
+ ir_to_mesa_src_reg return_reg;
+};
+
+class ir_to_mesa_visitor : public ir_visitor {
+public:
+ ir_to_mesa_visitor();
+ ~ir_to_mesa_visitor();
+
+ function_entry *current_function;
+
+ GLcontext *ctx;
+ struct gl_program *prog;
+ struct gl_shader_program *shader_program;
+
+ int next_temp;
+
+ variable_storage *find_variable_storage(ir_variable *var);
+
+ function_entry *get_function_signature(ir_function_signature *sig);
+
+ ir_to_mesa_src_reg get_temp(const glsl_type *type);
+ void reladdr_to_temp(ir_instruction *ir,
+ ir_to_mesa_src_reg *reg, int *num_reladdr);
+
+ struct ir_to_mesa_src_reg src_reg_for_float(float val);
+
+ /**
+ * \name Visit methods
+ *
+ * As typical for the visitor pattern, there must be one \c visit method for
+ * each concrete subclass of \c ir_instruction. Virtual base classes within
+ * the hierarchy should not have \c visit methods.
+ */
+ /*@{*/
+ virtual void visit(ir_variable *);
+ virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
+ virtual void visit(ir_function_signature *);
+ virtual void visit(ir_function *);
+ virtual void visit(ir_expression *);
+ virtual void visit(ir_swizzle *);
+ virtual void visit(ir_dereference_variable *);
+ virtual void visit(ir_dereference_array *);
+ virtual void visit(ir_dereference_record *);
+ virtual void visit(ir_assignment *);
+ virtual void visit(ir_constant *);
+ virtual void visit(ir_call *);
+ virtual void visit(ir_return *);
+ virtual void visit(ir_discard *);
+ virtual void visit(ir_texture *);
+ virtual void visit(ir_if *);
+ /*@}*/
+
+ struct ir_to_mesa_src_reg result;
+
+ /** List of variable_storage */
+ exec_list variables;
+
+ /** List of function_entry */
+ exec_list function_signatures;
+ int next_signature_id;
+
+ /** List of ir_to_mesa_instruction */
+ exec_list instructions;
+
+ ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir,
+ enum prog_opcode op);
+
+ ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0);
+
+ ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1);
+
+ ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1,
+ ir_to_mesa_src_reg src2);
+
+ void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0);
+
+ void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1);
+
+ GLboolean try_emit_mad(ir_expression *ir,
+ int mul_operand);
+
+ int get_sampler_uniform_value(ir_dereference *deref);
+
+ void *mem_ctx;
+};
+
+ir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL);
+
+ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
+ PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL,
+};
+
+ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
+ PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL
+};
+
+static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3);
+
+static void fail_link(struct gl_shader_program *prog, const char *fmt, ...)
+ {
+ va_list args;
+ va_start(args, fmt);
+ prog->InfoLog = talloc_vasprintf_append(prog->InfoLog, fmt, args);
+ va_end(args);
+
+ prog->LinkStatus = GL_FALSE;
+ }
+
+static int swizzle_for_size(int size)
+{
+ int size_swizzles[4] = {
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
+ };
+
+ return size_swizzles[size - 1];
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1,
+ ir_to_mesa_src_reg src2)
+{
+ ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
+ int num_reladdr = 0;
+
+ /* If we have to do relative addressing, we want to load the ARL
+ * reg directly for one of the regs, and preload the other reladdr
+ * sources into temps.
+ */
+ num_reladdr += dst.reladdr != NULL;
+ num_reladdr += src0.reladdr != NULL;
+ num_reladdr += src1.reladdr != NULL;
+ num_reladdr += src2.reladdr != NULL;
+
+ reladdr_to_temp(ir, &src2, &num_reladdr);
+ reladdr_to_temp(ir, &src1, &num_reladdr);
+ reladdr_to_temp(ir, &src0, &num_reladdr);
+
+ if (dst.reladdr) {
+ ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
+ *dst.reladdr);
+
+ num_reladdr--;
+ }
+ assert(num_reladdr == 0);
+
+ inst->op = op;
+ inst->dst_reg = dst;
+ inst->src_reg[0] = src0;
+ inst->src_reg[1] = src1;
+ inst->src_reg[2] = src2;
+ inst->ir = ir;
+
+ inst->function = NULL;
+
+ this->instructions.push_tail(inst);
+
+ return inst;
+}
+
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1)
+{
+ return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0)
+{
+ assert(dst.writemask != 0);
+ return ir_to_mesa_emit_op3(ir, op, dst,
+ src0, ir_to_mesa_undef, ir_to_mesa_undef);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
+ enum prog_opcode op)
+{
+ return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst,
+ ir_to_mesa_undef,
+ ir_to_mesa_undef,
+ ir_to_mesa_undef);
+}
+
+inline ir_to_mesa_dst_reg
+ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
+{
+ ir_to_mesa_dst_reg dst_reg;
+
+ dst_reg.file = reg.file;
+ dst_reg.index = reg.index;
+ dst_reg.writemask = WRITEMASK_XYZW;
+ dst_reg.cond_mask = COND_TR;
+ dst_reg.reladdr = reg.reladdr;
+
+ return dst_reg;
+}
+
+inline ir_to_mesa_src_reg
+ir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
+{
+ return ir_to_mesa_src_reg(reg.file, reg.index, NULL);
+}
+
+/**
+ * Emits Mesa scalar opcodes to produce unique answers across channels.
+ *
+ * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X
+ * channel determines the result across all channels. So to do a vec4
+ * of this operation, we want to emit a scalar per source channel used
+ * to produce dest channels.
+ */
+void
+ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg orig_src0,
+ ir_to_mesa_src_reg orig_src1)
+{
+ int i, j;
+ int done_mask = ~dst.writemask;
+
+ /* Mesa RCP is a scalar operation splatting results to all channels,
+ * like ARB_fp/vp. So emit as many RCPs as necessary to cover our
+ * dst channels.
+ */
+ for (i = 0; i < 4; i++) {
+ GLuint this_mask = (1 << i);
+ ir_to_mesa_instruction *inst;
+ ir_to_mesa_src_reg src0 = orig_src0;
+ ir_to_mesa_src_reg src1 = orig_src1;
+
+ if (done_mask & this_mask)
+ continue;
+
+ GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
+ GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
+ for (j = i + 1; j < 4; j++) {
+ if (!(done_mask & (1 << j)) &&
+ GET_SWZ(src0.swizzle, j) == src0_swiz &&
+ GET_SWZ(src1.swizzle, j) == src1_swiz) {
+ this_mask |= (1 << j);
+ }
+ }
+ src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
+ src0_swiz, src0_swiz);
+ src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
+ src1_swiz, src1_swiz);
+
+ inst = ir_to_mesa_emit_op2(ir, op,
+ dst,
+ src0,
+ src1);
+ inst->dst_reg.writemask = this_mask;
+ done_mask |= this_mask;
+ }
+}
+
+void
+ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
+ enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0)
+{
+ ir_to_mesa_src_reg undef = ir_to_mesa_undef;
+
+ undef.swizzle = SWIZZLE_XXXX;
+
+ ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
+}
+
+struct ir_to_mesa_src_reg
+ir_to_mesa_visitor::src_reg_for_float(float val)
+{
+ ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL);
+
+ src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+ &val, 1, &src_reg.swizzle);
+
+ return src_reg;
+}
+
+static int
+type_size(const struct glsl_type *type)
+{
+ unsigned int i;
+ int size;
+
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ if (type->is_matrix()) {
+ return type->matrix_columns;
+ } else {
+ /* Regardless of size of vector, it gets a vec4. This is bad
+ * packing for things like floats, but otherwise arrays become a
+ * mess. Hopefully a later pass over the code can pack scalars
+ * down if appropriate.
+ */
+ return 1;
+ }
+ case GLSL_TYPE_ARRAY:
+ return type_size(type->fields.array) * type->length;
+ case GLSL_TYPE_STRUCT:
+ size = 0;
+ for (i = 0; i < type->length; i++) {
+ size += type_size(type->fields.structure[i].type);
+ }
+ return size;
+ case GLSL_TYPE_SAMPLER:
+ /* Samplers take up one slot in UNIFORMS[], but they're baked in
+ * at link time.
+ */
+ return 1;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results. (not SSA -- variable assignments will reuse
+ * storage). Actual register allocation for the Mesa VM occurs in a
+ * pass over the Mesa IR later.
+ */
+ir_to_mesa_src_reg
+ir_to_mesa_visitor::get_temp(const glsl_type *type)
+{
+ ir_to_mesa_src_reg src_reg;
+ int swizzle[4];
+ int i;
+
+ src_reg.file = PROGRAM_TEMPORARY;
+ src_reg.index = next_temp;
+ src_reg.reladdr = NULL;
+ next_temp += type_size(type);
+
+ if (type->is_array() || type->is_record()) {
+ src_reg.swizzle = SWIZZLE_NOOP;
+ } else {
+ for (i = 0; i < type->vector_elements; i++)
+ swizzle[i] = i;
+ for (; i < 4; i++)
+ swizzle[i] = type->vector_elements - 1;
+ src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
+ swizzle[2], swizzle[3]);
+ }
+ src_reg.negate = 0;
+
+ return src_reg;
+}
+
+variable_storage *
+ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
+{
+
+ variable_storage *entry;
+
+ foreach_iter(exec_list_iterator, iter, this->variables) {
+ entry = (variable_storage *)iter.get();
+
+ if (entry->var == var)
+ return entry;
+ }
+
+ return NULL;
+}
+
+struct statevar_element {
+ const char *field;
+ int tokens[STATE_LENGTH];
+ int swizzle;
+ bool array_indexed;
+};
+
+static struct statevar_element gl_DepthRange_elements[] = {
+ {"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
+ {"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY},
+ {"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ},
+};
+
+static struct statevar_element gl_ClipPlane_elements[] = {
+ {NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW}
+};
+
+static struct statevar_element gl_Point_elements[] = {
+ {"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX},
+ {"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY},
+ {"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ},
+ {"fadeThresholdSize", {STATE_POINT_SIZE}, SWIZZLE_WWWW},
+ {"distanceConstantAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX},
+ {"distanceLinearAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY},
+ {"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ},
+};
+
+static struct statevar_element gl_FrontMaterial_elements[] = {
+ {"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
+ {"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
+ {"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
+ {"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
+ {"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
+};
+
+static struct statevar_element gl_BackMaterial_elements[] = {
+ {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
+ {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
+ {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
+ {"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
+ {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
+};
+
+static struct statevar_element gl_LightSource_elements[] = {
+ {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
+ {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
+ {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
+ {"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW},
+ {"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW},
+ {"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_XYZW},
+ {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW},
+ {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX},
+ {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW},
+ {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX},
+ {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY},
+ {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ},
+};
+
+static struct statevar_element gl_LightModel_elements[] = {
+ {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_FrontLightModelProduct_elements[] = {
+ {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_BackLightModelProduct_elements[] = {
+ {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_FrontLightProduct_elements[] = {
+ {"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
+ {"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
+ {"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_BackLightProduct_elements[] = {
+ {"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
+ {"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
+ {"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_TextureEnvColor_elements[] = {
+ {NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_EyePlaneS_elements[] = {
+ {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_EyePlaneT_elements[] = {
+ {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_EyePlaneR_elements[] = {
+ {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_EyePlaneQ_elements[] = {
+ {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_ObjectPlaneS_elements[] = {
+ {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_ObjectPlaneT_elements[] = {
+ {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_ObjectPlaneR_elements[] = {
+ {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_ObjectPlaneQ_elements[] = {
+ {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW},
+};
+
+static struct statevar_element gl_Fog_elements[] = {
+ {"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW},
+ {"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX},
+ {"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY},
+ {"end", {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ},
+ {"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW},
+};
+
+#define MATRIX(name, statevar, modifier) \
+ static struct statevar_element name ## _elements[] = { \
+ { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \
+ { NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW }, \
+ { NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW }, \
+ { NULL, { statevar, 0, 3, 3, modifier}, SWIZZLE_XYZW }, \
+ }
+
+MATRIX(gl_ModelViewMatrix,
+ STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE);
+MATRIX(gl_ModelViewMatrixInverse,
+ STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS);
+MATRIX(gl_ModelViewMatrixTranspose,
+ STATE_MODELVIEW_MATRIX, 0);
+MATRIX(gl_ModelViewMatrixInverseTranspose,
+ STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE);
+
+MATRIX(gl_ProjectionMatrix,
+ STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE);
+MATRIX(gl_ProjectionMatrixInverse,
+ STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS);
+MATRIX(gl_ProjectionMatrixTranspose,
+ STATE_PROJECTION_MATRIX, 0);
+MATRIX(gl_ProjectionMatrixInverseTranspose,
+ STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE);
+
+MATRIX(gl_ModelViewProjectionMatrix,
+ STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE);
+MATRIX(gl_ModelViewProjectionMatrixInverse,
+ STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS);
+MATRIX(gl_ModelViewProjectionMatrixTranspose,
+ STATE_MVP_MATRIX, 0);
+MATRIX(gl_ModelViewProjectionMatrixInverseTranspose,
+ STATE_MVP_MATRIX, STATE_MATRIX_INVERSE);
+
+MATRIX(gl_TextureMatrix,
+ STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE);
+MATRIX(gl_TextureMatrixInverse,
+ STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS);
+MATRIX(gl_TextureMatrixTranspose,
+ STATE_TEXTURE_MATRIX, 0);
+MATRIX(gl_TextureMatrixInverseTranspose,
+ STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE);
+
+static struct statevar_element gl_NormalMatrix_elements[] = {
+ { NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
+ SWIZZLE_XYZW },
+ { NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
+ SWIZZLE_XYZW },
+ { NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE},
+ SWIZZLE_XYZW },
+};
+
+#undef MATRIX
+
+#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
+
+static struct {
+ const char *name;
+ struct statevar_element *elements;
+ int num_elements;
+} statevars[] = {
+ STATEVAR(gl_DepthRange),
+ STATEVAR(gl_ClipPlane),
+ STATEVAR(gl_Point),
+ STATEVAR(gl_FrontMaterial),
+ STATEVAR(gl_BackMaterial),
+ STATEVAR(gl_LightSource),
+ STATEVAR(gl_LightModel),
+ STATEVAR(gl_FrontLightModelProduct),
+ STATEVAR(gl_BackLightModelProduct),
+ STATEVAR(gl_FrontLightProduct),
+ STATEVAR(gl_BackLightProduct),
+ STATEVAR(gl_TextureEnvColor),
+ STATEVAR(gl_EyePlaneS),
+ STATEVAR(gl_EyePlaneT),
+ STATEVAR(gl_EyePlaneR),
+ STATEVAR(gl_EyePlaneQ),
+ STATEVAR(gl_ObjectPlaneS),
+ STATEVAR(gl_ObjectPlaneT),
+ STATEVAR(gl_ObjectPlaneR),
+ STATEVAR(gl_ObjectPlaneQ),
+ STATEVAR(gl_Fog),
+
+ STATEVAR(gl_ModelViewMatrix),
+ STATEVAR(gl_ModelViewMatrixInverse),
+ STATEVAR(gl_ModelViewMatrixTranspose),
+ STATEVAR(gl_ModelViewMatrixInverseTranspose),
+
+ STATEVAR(gl_ProjectionMatrix),
+ STATEVAR(gl_ProjectionMatrixInverse),
+ STATEVAR(gl_ProjectionMatrixTranspose),
+ STATEVAR(gl_ProjectionMatrixInverseTranspose),
+
+ STATEVAR(gl_ModelViewProjectionMatrix),
+ STATEVAR(gl_ModelViewProjectionMatrixInverse),
+ STATEVAR(gl_ModelViewProjectionMatrixTranspose),
+ STATEVAR(gl_ModelViewProjectionMatrixInverseTranspose),
+
+ STATEVAR(gl_TextureMatrix),
+ STATEVAR(gl_TextureMatrixInverse),
+ STATEVAR(gl_TextureMatrixTranspose),
+ STATEVAR(gl_TextureMatrixInverseTranspose),
+
+ STATEVAR(gl_NormalMatrix),
+};
+
+void
+ir_to_mesa_visitor::visit(ir_variable *ir)
+{
+ if (strcmp(ir->name, "gl_FragCoord") == 0) {
+ struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
+
+ fp->OriginUpperLeft = ir->origin_upper_left;
+ fp->PixelCenterInteger = ir->pixel_center_integer;
+ }
+
+ if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
+ unsigned int i;
+
+ struct variable_storage *entry;
+ entry = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY,
+ this->next_temp);
+ this->variables.push_tail(entry);
+ this->next_temp += type_size(ir->type);
+
+ for (i = 0; i < Elements(statevars); i++) {
+ if (strcmp(ir->name, statevars[i].name) == 0)
+ break;
+ }
+
+ if (i == Elements(statevars)) {
+ fail_link(this->shader_program,
+ "Failed to find builtin uniform `%s'\n", ir->name);
+ return;
+ }
+
+ ir_to_mesa_dst_reg dst =
+ ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg(PROGRAM_TEMPORARY,
+ entry->index, NULL));
+
+ int array_count;
+ if (ir->type->is_array()) {
+ array_count = ir->type->length;
+ } else {
+ array_count = 1;
+ }
+
+ for (int a = 0; a < array_count; a++) {
+ for (int j = 0; j < statevars[i].num_elements; j++) {
+ struct statevar_element *element = &statevars[i].elements[j];
+ int tokens[STATE_LENGTH];
+
+ memcpy(tokens, element->tokens, sizeof(element->tokens));
+ if (ir->type->is_array()) {
+ tokens[1] = a;
+ }
+
+ int index = _mesa_add_state_reference(this->prog->Parameters,
+ (gl_state_index *)tokens);
+ ir_to_mesa_src_reg src(PROGRAM_STATE_VAR, index, NULL);
+ src.swizzle = element->swizzle;
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, dst, src);
+ /* even a float takes up a whole vec4 reg in a struct/array. */
+ dst.index++;
+ }
+ }
+ if (dst.index != entry->index + type_size(ir->type)) {
+ fail_link(this->shader_program,
+ "failed to load builtin uniform `%s' (%d/%d regs loaded)\n",
+ ir->name, dst.index - entry->index,
+ type_size(ir->type));
+ }
+ }
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop *ir)
+{
+ assert(!ir->from);
+ assert(!ir->to);
+ assert(!ir->increment);
+ assert(!ir->counter);
+
+ ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP);
+ visit_exec_list(&ir->body_instructions, this);
+ ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop_jump *ir)
+{
+ switch (ir->mode) {
+ case ir_loop_jump::jump_break:
+ ir_to_mesa_emit_op0(NULL, OPCODE_BRK);
+ break;
+ case ir_loop_jump::jump_continue:
+ ir_to_mesa_emit_op0(NULL, OPCODE_CONT);
+ break;
+ }
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_function_signature *ir)
+{
+ assert(0);
+ (void)ir;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_function *ir)
+{
+ /* Ignore function bodies other than main() -- we shouldn't see calls to
+ * them since they should all be inlined before we get to ir_to_mesa.
+ */
+ if (strcmp(ir->name, "main") == 0) {
+ const ir_function_signature *sig;
+ exec_list empty;
+
+ sig = ir->matching_signature(&empty);
+
+ assert(sig);
+
+ foreach_iter(exec_list_iterator, iter, sig->body) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+
+ ir->accept(this);
+ }
+ }
+}
+
+GLboolean
+ir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
+{
+ int nonmul_operand = 1 - mul_operand;
+ ir_to_mesa_src_reg a, b, c;
+
+ ir_expression *expr = ir->operands[mul_operand]->as_expression();
+ if (!expr || expr->operation != ir_binop_mul)
+ return false;
+
+ expr->operands[0]->accept(this);
+ a = this->result;
+ expr->operands[1]->accept(this);
+ b = this->result;
+ ir->operands[nonmul_operand]->accept(this);
+ c = this->result;
+
+ this->result = get_temp(ir->type);
+ ir_to_mesa_emit_op3(ir, OPCODE_MAD,
+ ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
+
+ return true;
+}
+
+void
+ir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
+ ir_to_mesa_src_reg *reg, int *num_reladdr)
+{
+ if (!reg->reladdr)
+ return;
+
+ ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr);
+
+ if (*num_reladdr != 1) {
+ ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
+
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV,
+ ir_to_mesa_dst_reg_from_src(temp), *reg);
+ *reg = temp;
+ }
+
+ (*num_reladdr)--;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_expression *ir)
+{
+ unsigned int operand;
+ struct ir_to_mesa_src_reg op[2];
+ struct ir_to_mesa_src_reg result_src;
+ struct ir_to_mesa_dst_reg result_dst;
+ const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
+ const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
+ const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
+
+ /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
+ */
+ if (ir->operation == ir_binop_add) {
+ if (try_emit_mad(ir, 1))
+ return;
+ if (try_emit_mad(ir, 0))
+ return;
+ }
+
+ for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ this->result.file = PROGRAM_UNDEFINED;
+ ir->operands[operand]->accept(this);
+ if (this->result.file == PROGRAM_UNDEFINED) {
+ ir_print_visitor v;
+ printf("Failed to get tree for expression operand:\n");
+ ir->operands[operand]->accept(&v);
+ exit(1);
+ }
+ op[operand] = this->result;
+
+ /* Matrix expression operands should have been broken down to vector
+ * operations already.
+ */
+ assert(!ir->operands[operand]->type->is_matrix());
+ }
+
+ this->result.file = PROGRAM_UNDEFINED;
+
+ /* Storage for our result. Ideally for an assignment we'd be using
+ * the actual storage for the result here, instead.
+ */
+ result_src = get_temp(ir->type);
+ /* convenience for the emit functions below. */
+ result_dst = ir_to_mesa_dst_reg_from_src(result_src);
+ /* Limit writes to the channels that will be used by result_src later.
+ * This does limit this temp's use as a temporary for multi-instruction
+ * sequences.
+ */
+ result_dst.writemask = (1 << ir->type->vector_elements) - 1;
+
+ switch (ir->operation) {
+ case ir_unop_logic_not:
+ ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
+ op[0], src_reg_for_float(0.0));
+ break;
+ case ir_unop_neg:
+ op[0].negate = ~op[0].negate;
+ result_src = op[0];
+ break;
+ case ir_unop_abs:
+ ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
+ break;
+ case ir_unop_sign:
+ ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
+ break;
+ case ir_unop_rcp:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
+ break;
+
+ case ir_unop_exp2:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
+ break;
+ case ir_unop_exp:
+ case ir_unop_log:
+ assert(!"not reached: should be handled by ir_explog_to_explog2");
+ break;
+ case ir_unop_log2:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
+ break;
+ case ir_unop_sin:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
+ break;
+ case ir_unop_cos:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
+ break;
+
+ case ir_unop_dFdx:
+ ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
+ break;
+ case ir_unop_dFdy:
+ ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
+ break;
+
+ case ir_binop_add:
+ ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_sub:
+ ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
+ break;
+
+ case ir_binop_mul:
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_div:
+ assert(!"not reached: should be handled by ir_div_to_mul_rcp");
+ case ir_binop_mod:
+ assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
+ break;
+
+ case ir_binop_less:
+ ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_greater:
+ ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_lequal:
+ ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_gequal:
+ ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_equal:
+ /* "==" operator producing a scalar boolean. */
+ if (ir->operands[0]->type->is_vector() ||
+ ir->operands[1]->type->is_vector()) {
+ ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+ ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
+ ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
+ ir_to_mesa_emit_op2(ir, OPCODE_SEQ,
+ result_dst, result_src, src_reg_for_float(0.0));
+ } else {
+ ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
+ }
+ break;
+ case ir_binop_nequal:
+ /* "!=" operator producing a scalar boolean. */
+ if (ir->operands[0]->type->is_vector() ||
+ ir->operands[1]->type->is_vector()) {
+ ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+ ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]);
+ ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp);
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+ result_dst, result_src, src_reg_for_float(0.0));
+ } else {
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+ }
+ break;
+
+ case ir_unop_any:
+ switch (ir->operands[0]->type->vector_elements) {
+ case 4:
+ ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, op[0], op[0]);
+ break;
+ case 3:
+ ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, op[0], op[0]);
+ break;
+ case 2:
+ ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, op[0], op[0]);
+ break;
+ default:
+ assert(!"unreached: ir_unop_any of non-bvec");
+ break;
+ }
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+ result_dst, result_src, src_reg_for_float(0.0));
+ break;
+
+ case ir_binop_logic_xor:
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+ break;
+
+ case ir_binop_logic_or:
+ /* This could be a saturated add and skip the SNE. */
+ ir_to_mesa_emit_op2(ir, OPCODE_ADD,
+ result_dst,
+ op[0], op[1]);
+
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+ result_dst,
+ result_src, src_reg_for_float(0.0));
+ break;
+
+ case ir_binop_logic_and:
+ /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+ result_dst,
+ op[0], op[1]);
+ break;
+
+ case ir_binop_dot:
+ if (ir->operands[0]->type == vec4_type) {
+ assert(ir->operands[1]->type == vec4_type);
+ ir_to_mesa_emit_op2(ir, OPCODE_DP4,
+ result_dst,
+ op[0], op[1]);
+ } else if (ir->operands[0]->type == vec3_type) {
+ assert(ir->operands[1]->type == vec3_type);
+ ir_to_mesa_emit_op2(ir, OPCODE_DP3,
+ result_dst,
+ op[0], op[1]);
+ } else if (ir->operands[0]->type == vec2_type) {
+ assert(ir->operands[1]->type == vec2_type);
+ ir_to_mesa_emit_op2(ir, OPCODE_DP2,
+ result_dst,
+ op[0], op[1]);
+ }
+ break;
+
+ case ir_binop_cross:
+ ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]);
+ break;
+
+ case ir_unop_sqrt:
+ /* sqrt(x) = x * rsq(x). */
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, result_src, op[0]);
+ /* For incoming channels <= 0, set the result to 0. */
+ op[0].negate = ~op[0].negate;
+ ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
+ op[0], result_src, src_reg_for_float(0.0));
+ break;
+ case ir_unop_rsq:
+ ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
+ break;
+ case ir_unop_i2f:
+ case ir_unop_b2f:
+ case ir_unop_b2i:
+ /* Mesa IR lacks types, ints are stored as truncated floats. */
+ result_src = op[0];
+ break;
+ case ir_unop_f2i:
+ ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
+ break;
+ case ir_unop_f2b:
+ case ir_unop_i2b:
+ ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
+ op[0], src_reg_for_float(0.0));
+ break;
+ case ir_unop_trunc:
+ ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
+ break;
+ case ir_unop_ceil:
+ op[0].negate = ~op[0].negate;
+ ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
+ result_src.negate = ~result_src.negate;
+ break;
+ case ir_unop_floor:
+ ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
+ break;
+ case ir_unop_fract:
+ ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
+ break;
+
+ case ir_binop_min:
+ ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_max:
+ ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
+ break;
+ case ir_binop_pow:
+ ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
+ break;
+
+ case ir_unop_bit_not:
+ case ir_unop_u2f:
+ case ir_binop_lshift:
+ case ir_binop_rshift:
+ case ir_binop_bit_and:
+ case ir_binop_bit_xor:
+ case ir_binop_bit_or:
+ assert(!"GLSL 1.30 features unsupported");
+ break;
+ }
+
+ this->result = result_src;
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_swizzle *ir)
+{
+ ir_to_mesa_src_reg src_reg;
+ int i;
+ int swizzle[4];
+
+ /* Note that this is only swizzles in expressions, not those on the left
+ * hand side of an assignment, which do write masking. See ir_assignment
+ * for that.
+ */
+
+ ir->val->accept(this);
+ src_reg = this->result;
+ assert(src_reg.file != PROGRAM_UNDEFINED);
+
+ for (i = 0; i < 4; i++) {
+ if (i < ir->type->vector_elements) {
+ switch (i) {
+ case 0:
+ swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
+ break;
+ case 1:
+ swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
+ break;
+ case 2:
+ swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
+ break;
+ case 3:
+ swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
+ break;
+ }
+ } else {
+ /* If the type is smaller than a vec4, replicate the last
+ * channel out.
+ */
+ swizzle[i] = swizzle[ir->type->vector_elements - 1];
+ }
+ }
+
+ src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
+ swizzle[1],
+ swizzle[2],
+ swizzle[3]);
+
+ this->result = src_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
+{
+ variable_storage *entry = find_variable_storage(ir->var);
+
+ if (!entry) {
+ switch (ir->var->mode) {
+ case ir_var_uniform:
+ entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM,
+ ir->var->location);
+ this->variables.push_tail(entry);
+ break;
+ case ir_var_in:
+ case ir_var_out:
+ case ir_var_inout:
+ /* The linker assigns locations for varyings and attributes,
+ * including deprecated builtins (like gl_Color), user-assign
+ * generic attributes (glBindVertexLocation), and
+ * user-defined varyings.
+ *
+ * FINISHME: We would hit this path for function arguments. Fix!
+ */
+ assert(ir->var->location != -1);
+ if (ir->var->mode == ir_var_in ||
+ ir->var->mode == ir_var_inout) {
+ entry = new(mem_ctx) variable_storage(ir->var,
+ PROGRAM_INPUT,
+ ir->var->location);
+
+ if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
+ ir->var->location >= VERT_ATTRIB_GENERIC0) {
+ _mesa_add_attribute(prog->Attributes,
+ ir->var->name,
+ _mesa_sizeof_glsl_type(ir->var->type->gl_type),
+ ir->var->type->gl_type,
+ ir->var->location - VERT_ATTRIB_GENERIC0);
+ }
+ } else {
+ entry = new(mem_ctx) variable_storage(ir->var,
+ PROGRAM_OUTPUT,
+ ir->var->location);
+ }
+
+ break;
+ case ir_var_auto:
+ case ir_var_temporary:
+ entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
+ this->next_temp);
+ this->variables.push_tail(entry);
+
+ next_temp += type_size(ir->var->type);
+ break;
+ }
+
+ if (!entry) {
+ printf("Failed to make storage for %s\n", ir->var->name);
+ exit(1);
+ }
+ }
+
+ this->result = ir_to_mesa_src_reg(entry->file, entry->index, ir->var->type);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_array *ir)
+{
+ ir_constant *index;
+ ir_to_mesa_src_reg src_reg;
+ int element_size = type_size(ir->type);
+
+ index = ir->array_index->constant_expression_value();
+
+ ir->array->accept(this);
+ src_reg = this->result;
+
+ if (index) {
+ src_reg.index += index->value.i[0] * element_size;
+ } else {
+ ir_to_mesa_src_reg array_base = this->result;
+ /* Variable index array dereference. It eats the "vec4" of the
+ * base of the array and an index that offsets the Mesa register
+ * index.
+ */
+ ir->array_index->accept(this);
+
+ ir_to_mesa_src_reg index_reg;
+
+ if (element_size == 1) {
+ index_reg = this->result;
+ } else {
+ index_reg = get_temp(glsl_type::float_type);
+
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+ ir_to_mesa_dst_reg_from_src(index_reg),
+ this->result, src_reg_for_float(element_size));
+ }
+
+ src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
+ memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
+ }
+
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ if (ir->type->is_scalar() || ir->type->is_vector())
+ src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
+ else
+ src_reg.swizzle = SWIZZLE_NOOP;
+
+ this->result = src_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_record *ir)
+{
+ unsigned int i;
+ const glsl_type *struct_type = ir->record->type;
+ int offset = 0;
+
+ ir->record->accept(this);
+
+ for (i = 0; i < struct_type->length; i++) {
+ if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
+ break;
+ offset += type_size(struct_type->fields.structure[i].type);
+ }
+ this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
+ this->result.index += offset;
+}
+
+/**
+ * We want to be careful in assignment setup to hit the actual storage
+ * instead of potentially using a temporary like we might with the
+ * ir_dereference handler.
+ */
+static struct ir_to_mesa_dst_reg
+get_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v)
+{
+ /* The LHS must be a dereference. If the LHS is a variable indexed array
+ * access of a vector, it must be separated into a series conditional moves
+ * before reaching this point (see ir_vec_index_to_cond_assign).
+ */
+ assert(ir->as_dereference());
+ ir_dereference_array *deref_array = ir->as_dereference_array();
+ if (deref_array) {
+ assert(!deref_array->array->type->is_vector());
+ }
+
+ /* Use the rvalue deref handler for the most part. We'll ignore
+ * swizzles in it and write swizzles using writemask, though.
+ */
+ ir->accept(v);
+ return ir_to_mesa_dst_reg_from_src(v->result);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_assignment *ir)
+{
+ struct ir_to_mesa_dst_reg l;
+ struct ir_to_mesa_src_reg r;
+ int i;
+
+ ir->rhs->accept(this);
+ r = this->result;
+
+ l = get_assignment_lhs(ir->lhs, this);
+
+ /* FINISHME: This should really set to the correct maximal writemask for each
+ * FINISHME: component written (in the loops below). This case can only
+ * FINISHME: occur for matrices, arrays, and structures.
+ */
+ if (ir->write_mask == 0) {
+ assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());
+ l.writemask = WRITEMASK_XYZW;
+ } else if (ir->lhs->type->is_scalar()) {
+ /* FINISHME: This hack makes writing to gl_FragData, which lives in the
+ * FINISHME: W component of fragment shader output zero, work correctly.
+ */
+ l.writemask = WRITEMASK_XYZW;
+ } else {
+ assert(ir->lhs->type->is_vector());
+ l.writemask = ir->write_mask;
+ }
+
+ assert(l.file != PROGRAM_UNDEFINED);
+ assert(r.file != PROGRAM_UNDEFINED);
+
+ if (ir->condition) {
+ ir_to_mesa_src_reg condition;
+
+ ir->condition->accept(this);
+ condition = this->result;
+
+ /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
+ * and the condition we produced is 0.0 or 1.0. By flipping the
+ * sign, we can choose which value OPCODE_CMP produces without
+ * an extra computing the condition.
+ */
+ condition.negate = ~condition.negate;
+ for (i = 0; i < type_size(ir->lhs->type); i++) {
+ ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
+ condition, r, ir_to_mesa_src_reg_from_dst(l));
+ l.index++;
+ r.index++;
+ }
+ } else {
+ for (i = 0; i < type_size(ir->lhs->type); i++) {
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+ l.index++;
+ r.index++;
+ }
+ }
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_constant *ir)
+{
+ ir_to_mesa_src_reg src_reg;
+ GLfloat stack_vals[4] = { 0 };
+ GLfloat *values = stack_vals;
+ unsigned int i;
+
+ /* Unfortunately, 4 floats is all we can get into
+ * _mesa_add_unnamed_constant. So, make a temp to store an
+ * aggregate constant and move each constant value into it. If we
+ * get lucky, copy propagation will eliminate the extra moves.
+ */
+
+ if (ir->type->base_type == GLSL_TYPE_STRUCT) {
+ ir_to_mesa_src_reg temp_base = get_temp(ir->type);
+ ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
+
+ foreach_iter(exec_list_iterator, iter, ir->components) {
+ ir_constant *field_value = (ir_constant *)iter.get();
+ int size = type_size(field_value->type);
+
+ assert(size > 0);
+
+ field_value->accept(this);
+ src_reg = this->result;
+
+ for (i = 0; i < (unsigned int)size; i++) {
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
+
+ src_reg.index++;
+ temp.index++;
+ }
+ }
+ this->result = temp_base;
+ return;
+ }
+
+ if (ir->type->is_array()) {
+ ir_to_mesa_src_reg temp_base = get_temp(ir->type);
+ ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
+ int size = type_size(ir->type->fields.array);
+
+ assert(size > 0);
+
+ for (i = 0; i < ir->type->length; i++) {
+ ir->array_elements[i]->accept(this);
+ src_reg = this->result;
+ for (int j = 0; j < size; j++) {
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
+
+ src_reg.index++;
+ temp.index++;
+ }
+ }
+ this->result = temp_base;
+ return;
+ }
+
+ if (ir->type->is_matrix()) {
+ ir_to_mesa_src_reg mat = get_temp(ir->type);
+ ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);
+
+ for (i = 0; i < ir->type->matrix_columns; i++) {
+ assert(ir->type->base_type == GLSL_TYPE_FLOAT);
+ values = &ir->value.f[i * ir->type->vector_elements];
+
+ src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL);
+ src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+ values,
+ ir->type->vector_elements,
+ &src_reg.swizzle);
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg);
+
+ mat_column.index++;
+ }
+
+ this->result = mat;
+ return;
+ }
+
+ src_reg.file = PROGRAM_CONSTANT;
+ switch (ir->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ values = &ir->value.f[0];
+ break;
+ case GLSL_TYPE_UINT:
+ for (i = 0; i < ir->type->vector_elements; i++) {
+ values[i] = ir->value.u[i];
+ }
+ break;
+ case GLSL_TYPE_INT:
+ for (i = 0; i < ir->type->vector_elements; i++) {
+ values[i] = ir->value.i[i];
+ }
+ break;
+ case GLSL_TYPE_BOOL:
+ for (i = 0; i < ir->type->vector_elements; i++) {
+ values[i] = ir->value.b[i];
+ }
+ break;
+ default:
+ assert(!"Non-float/uint/int/bool constant");
+ }
+
+ this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type);
+ this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+ values,
+ ir->type->vector_elements,
+ &this->result.swizzle);
+}
+
+function_entry *
+ir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
+{
+ function_entry *entry;
+
+ foreach_iter(exec_list_iterator, iter, this->function_signatures) {
+ entry = (function_entry *)iter.get();
+
+ if (entry->sig == sig)
+ return entry;
+ }
+
+ entry = talloc(mem_ctx, function_entry);
+ entry->sig = sig;
+ entry->sig_id = this->next_signature_id++;
+ entry->bgn_inst = NULL;
+
+ /* Allocate storage for all the parameters. */
+ foreach_iter(exec_list_iterator, iter, sig->parameters) {
+ ir_variable *param = (ir_variable *)iter.get();
+ variable_storage *storage;
+
+ storage = find_variable_storage(param);
+ assert(!storage);
+
+ storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
+ this->next_temp);
+ this->variables.push_tail(storage);
+
+ this->next_temp += type_size(param->type);
+ }
+
+ if (!sig->return_type->is_void()) {
+ entry->return_reg = get_temp(sig->return_type);
+ } else {
+ entry->return_reg = ir_to_mesa_undef;
+ }
+
+ this->function_signatures.push_tail(entry);
+ return entry;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_call *ir)
+{
+ ir_to_mesa_instruction *call_inst;
+ ir_function_signature *sig = ir->get_callee();
+ function_entry *entry = get_function_signature(sig);
+ int i;
+
+ /* Process in parameters. */
+ exec_list_iterator sig_iter = sig->parameters.iterator();
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_rvalue *param_rval = (ir_rvalue *)iter.get();
+ ir_variable *param = (ir_variable *)sig_iter.get();
+
+ if (param->mode == ir_var_in ||
+ param->mode == ir_var_inout) {
+ variable_storage *storage = find_variable_storage(param);
+ assert(storage);
+
+ param_rval->accept(this);
+ ir_to_mesa_src_reg r = this->result;
+
+ ir_to_mesa_dst_reg l;
+ l.file = storage->file;
+ l.index = storage->index;
+ l.reladdr = NULL;
+ l.writemask = WRITEMASK_XYZW;
+ l.cond_mask = COND_TR;
+
+ for (i = 0; i < type_size(param->type); i++) {
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+ l.index++;
+ r.index++;
+ }
+ }
+
+ sig_iter.next();
+ }
+ assert(!sig_iter.has_next());
+
+ /* Emit call instruction */
+ call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL,
+ ir_to_mesa_undef_dst, ir_to_mesa_undef);
+ call_inst->function = entry;
+
+ /* Process out parameters. */
+ sig_iter = sig->parameters.iterator();
+ foreach_iter(exec_list_iterator, iter, *ir) {
+ ir_rvalue *param_rval = (ir_rvalue *)iter.get();
+ ir_variable *param = (ir_variable *)sig_iter.get();
+
+ if (param->mode == ir_var_out ||
+ param->mode == ir_var_inout) {
+ variable_storage *storage = find_variable_storage(param);
+ assert(storage);
+
+ ir_to_mesa_src_reg r;
+ r.file = storage->file;
+ r.index = storage->index;
+ r.reladdr = NULL;
+ r.swizzle = SWIZZLE_NOOP;
+ r.negate = 0;
+
+ param_rval->accept(this);
+ ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result);
+
+ for (i = 0; i < type_size(param->type); i++) {
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+ l.index++;
+ r.index++;
+ }
+ }
+
+ sig_iter.next();
+ }
+ assert(!sig_iter.has_next());
+
+ /* Process return value. */
+ this->result = entry->return_reg;
+}
+
+class get_sampler_name : public ir_hierarchical_visitor
+{
+public:
+ get_sampler_name(ir_to_mesa_visitor *mesa, ir_dereference *last)
+ {
+ this->mem_ctx = mesa->mem_ctx;
+ this->mesa = mesa;
+ this->name = NULL;
+ this->offset = 0;
+ this->last = last;
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ this->name = ir->var->name;
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
+ {
+ this->name = talloc_asprintf(mem_ctx, "%s.%s", name, ir->field);
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
+ {
+ ir_constant *index = ir->array_index->as_constant();
+ int i;
+
+ if (index) {
+ i = index->value.i[0];
+ } else {
+ /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
+ * while GLSL 1.30 requires that the array indices be
+ * constant integer expressions. We don't expect any driver
+ * to actually work with a really variable array index, so
+ * all that would work would be an unrolled loop counter that ends
+ * up being constant above.
+ */
+ mesa->shader_program->InfoLog =
+ talloc_asprintf_append(mesa->shader_program->InfoLog,
+ "warning: Variable sampler array index "
+ "unsupported.\nThis feature of the language "
+ "was removed in GLSL 1.20 and is unlikely "
+ "to be supported for 1.10 in Mesa.\n");
+ i = 0;
+ }
+ if (ir != last) {
+ this->name = talloc_asprintf(mem_ctx, "%s[%d]", name, i);
+ } else {
+ offset = i;
+ }
+ return visit_continue;
+ }
+
+ ir_to_mesa_visitor *mesa;
+ const char *name;
+ void *mem_ctx;
+ int offset;
+ ir_dereference *last;
+};
+
+int
+ir_to_mesa_visitor::get_sampler_uniform_value(ir_dereference *sampler)
+{
+ get_sampler_name getname(this, sampler);
+
+ sampler->accept(&getname);
+
+ GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
+ getname.name);
+
+ if (index < 0) {
+ fail_link(this->shader_program,
+ "failed to find sampler named %s.\n", getname.name);
+ return 0;
+ }
+
+ index += getname.offset;
+
+ return this->prog->Parameters->ParameterValues[index][0];
+}
+
+void
+ir_to_mesa_visitor::visit(ir_texture *ir)
+{
+ ir_to_mesa_src_reg result_src, coord, lod_info, projector;
+ ir_to_mesa_dst_reg result_dst, coord_dst;
+ ir_to_mesa_instruction *inst = NULL;
+ prog_opcode opcode = OPCODE_NOP;
+
+ ir->coordinate->accept(this);
+
+ /* Put our coords in a temp. We'll need to modify them for shadow,
+ * projection, or LOD, so the only case we'd use it as is is if
+ * we're doing plain old texturing. Mesa IR optimization should
+ * handle cleaning up our mess in that case.
+ */
+ coord = get_temp(glsl_type::vec4_type);
+ coord_dst = ir_to_mesa_dst_reg_from_src(coord);
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
+ this->result);
+
+ if (ir->projector) {
+ ir->projector->accept(this);
+ projector = this->result;
+ }
+
+ /* Storage for our result. Ideally for an assignment we'd be using
+ * the actual storage for the result here, instead.
+ */
+ result_src = get_temp(glsl_type::vec4_type);
+ result_dst = ir_to_mesa_dst_reg_from_src(result_src);
+
+ switch (ir->op) {
+ case ir_tex:
+ opcode = OPCODE_TEX;
+ break;
+ case ir_txb:
+ opcode = OPCODE_TXB;
+ ir->lod_info.bias->accept(this);
+ lod_info = this->result;
+ break;
+ case ir_txl:
+ opcode = OPCODE_TXL;
+ ir->lod_info.lod->accept(this);
+ lod_info = this->result;
+ break;
+ case ir_txd:
+ case ir_txf:
+ assert(!"GLSL 1.30 features unsupported");
+ break;
+ }
+
+ if (ir->projector) {
+ if (opcode == OPCODE_TEX) {
+ /* Slot the projector in as the last component of the coord. */
+ coord_dst.writemask = WRITEMASK_W;
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
+ coord_dst.writemask = WRITEMASK_XYZW;
+ opcode = OPCODE_TXP;
+ } else {
+ ir_to_mesa_src_reg coord_w = coord;
+ coord_w.swizzle = SWIZZLE_WWWW;
+
+ /* For the other TEX opcodes there's no projective version
+ * since the last slot is taken up by lod info. Do the
+ * projective divide now.
+ */
+ coord_dst.writemask = WRITEMASK_W;
+ ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
+
+ coord_dst.writemask = WRITEMASK_XYZ;
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
+
+ coord_dst.writemask = WRITEMASK_XYZW;
+ coord.swizzle = SWIZZLE_XYZW;
+ }
+ }
+
+ if (ir->shadow_comparitor) {
+ /* Slot the shadow value in as the second to last component of the
+ * coord.
+ */
+ ir->shadow_comparitor->accept(this);
+ coord_dst.writemask = WRITEMASK_Z;
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
+ coord_dst.writemask = WRITEMASK_XYZW;
+ }
+
+ if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
+ /* Mesa IR stores lod or lod bias in the last channel of the coords. */
+ coord_dst.writemask = WRITEMASK_W;
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
+ coord_dst.writemask = WRITEMASK_XYZW;
+ }
+
+ inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
+
+ if (ir->shadow_comparitor)
+ inst->tex_shadow = GL_TRUE;
+
+ inst->sampler = get_sampler_uniform_value(ir->sampler);
+
+ const glsl_type *sampler_type = ir->sampler->type;
+
+ switch (sampler_type->sampler_dimensionality) {
+ case GLSL_SAMPLER_DIM_1D:
+ inst->tex_target = (sampler_type->sampler_array)
+ ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_2D:
+ inst->tex_target = (sampler_type->sampler_array)
+ ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_3D:
+ inst->tex_target = TEXTURE_3D_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_CUBE:
+ inst->tex_target = TEXTURE_CUBE_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_RECT:
+ inst->tex_target = TEXTURE_RECT_INDEX;
+ break;
+ case GLSL_SAMPLER_DIM_BUF:
+ assert(!"FINISHME: Implement ARB_texture_buffer_object");
+ break;
+ default:
+ assert(!"Should not get here.");
+ }
+
+ this->result = result_src;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_return *ir)
+{
+ if (ir->get_value()) {
+ ir_to_mesa_dst_reg l;
+ int i;
+
+ assert(current_function);
+
+ ir->get_value()->accept(this);
+ ir_to_mesa_src_reg r = this->result;
+
+ l = ir_to_mesa_dst_reg_from_src(current_function->return_reg);
+
+ for (i = 0; i < type_size(current_function->sig->return_type); i++) {
+ ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+ l.index++;
+ r.index++;
+ }
+ }
+
+ ir_to_mesa_emit_op0(ir, OPCODE_RET);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_discard *ir)
+{
+ struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
+
+ assert(ir->condition == NULL); /* FINISHME */
+
+ ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
+ fp->UsesKill = GL_TRUE;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_if *ir)
+{
+ ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
+ ir_to_mesa_instruction *prev_inst;
+
+ prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
+
+ ir->condition->accept(this);
+ assert(this->result.file != PROGRAM_UNDEFINED);
+
+ if (ctx->Shader.EmitCondCodes) {
+ cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
+
+ /* See if we actually generated any instruction for generating
+ * the condition. If not, then cook up a move to a temp so we
+ * have something to set cond_update on.
+ */
+ if (cond_inst == prev_inst) {
+ ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
+ cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
+ ir_to_mesa_dst_reg_from_src(temp),
+ result);
+ }
+ cond_inst->cond_update = GL_TRUE;
+
+ if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF);
+ if_inst->dst_reg.cond_mask = COND_NE;
+ } else {
+ if_inst = ir_to_mesa_emit_op1(ir->condition,
+ OPCODE_IF, ir_to_mesa_undef_dst,
+ this->result);
+ }
+
+ this->instructions.push_tail(if_inst);
+
+ visit_exec_list(&ir->then_instructions, this);
+
+ if (!ir->else_instructions.is_empty()) {
+ else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE);
+ visit_exec_list(&ir->else_instructions, this);
+ }
+
+ if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
+ ir_to_mesa_undef_dst, ir_to_mesa_undef);
+}
+
+ir_to_mesa_visitor::ir_to_mesa_visitor()
+{
+ result.file = PROGRAM_UNDEFINED;
+ next_temp = 1;
+ next_signature_id = 1;
+ current_function = NULL;
+ mem_ctx = talloc_new(NULL);
+}
+
+ir_to_mesa_visitor::~ir_to_mesa_visitor()
+{
+ talloc_free(mem_ctx);
+}
+
+static struct prog_src_register
+mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
+{
+ struct prog_src_register mesa_reg;
+
+ mesa_reg.File = reg.file;
+ assert(reg.index < (1 << INST_INDEX_BITS) - 1);
+ mesa_reg.Index = reg.index;
+ mesa_reg.Swizzle = reg.swizzle;
+ mesa_reg.RelAddr = reg.reladdr != NULL;
+ mesa_reg.Negate = reg.negate;
+ mesa_reg.Abs = 0;
+ mesa_reg.HasIndex2 = GL_FALSE;
+ mesa_reg.RelAddr2 = 0;
+ mesa_reg.Index2 = 0;
+
+ return mesa_reg;
+}
+
+static void
+set_branchtargets(ir_to_mesa_visitor *v,
+ struct prog_instruction *mesa_instructions,
+ int num_instructions)
+{
+ int if_count = 0, loop_count = 0;
+ int *if_stack, *loop_stack;
+ int if_stack_pos = 0, loop_stack_pos = 0;
+ int i, j;
+
+ for (i = 0; i < num_instructions; i++) {
+ switch (mesa_instructions[i].Opcode) {
+ case OPCODE_IF:
+ if_count++;
+ break;
+ case OPCODE_BGNLOOP:
+ loop_count++;
+ break;
+ case OPCODE_BRK:
+ case OPCODE_CONT:
+ mesa_instructions[i].BranchTarget = -1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if_stack = talloc_zero_array(v->mem_ctx, int, if_count);
+ loop_stack = talloc_zero_array(v->mem_ctx, int, loop_count);
+
+ for (i = 0; i < num_instructions; i++) {
+ switch (mesa_instructions[i].Opcode) {
+ case OPCODE_IF:
+ if_stack[if_stack_pos] = i;
+ if_stack_pos++;
+ break;
+ case OPCODE_ELSE:
+ mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
+ if_stack[if_stack_pos - 1] = i;
+ break;
+ case OPCODE_ENDIF:
+ mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
+ if_stack_pos--;
+ break;
+ case OPCODE_BGNLOOP:
+ loop_stack[loop_stack_pos] = i;
+ loop_stack_pos++;
+ break;
+ case OPCODE_ENDLOOP:
+ loop_stack_pos--;
+ /* Rewrite any breaks/conts at this nesting level (haven't
+ * already had a BranchTarget assigned) to point to the end
+ * of the loop.
+ */
+ for (j = loop_stack[loop_stack_pos]; j < i; j++) {
+ if (mesa_instructions[j].Opcode == OPCODE_BRK ||
+ mesa_instructions[j].Opcode == OPCODE_CONT) {
+ if (mesa_instructions[j].BranchTarget == -1) {
+ mesa_instructions[j].BranchTarget = i;
+ }
+ }
+ }
+ /* The loop ends point at each other. */
+ mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
+ mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
+ break;
+ case OPCODE_CAL:
+ foreach_iter(exec_list_iterator, iter, v->function_signatures) {
+ function_entry *entry = (function_entry *)iter.get();
+
+ if (entry->sig_id == mesa_instructions[i].BranchTarget) {
+ mesa_instructions[i].BranchTarget = entry->inst;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void
+print_program(struct prog_instruction *mesa_instructions,
+ ir_instruction **mesa_instruction_annotation,
+ int num_instructions)
+{
+ ir_instruction *last_ir = NULL;
+ int i;
+ int indent = 0;
+
+ for (i = 0; i < num_instructions; i++) {
+ struct prog_instruction *mesa_inst = mesa_instructions + i;
+ ir_instruction *ir = mesa_instruction_annotation[i];
+
+ fprintf(stdout, "%3d: ", i);
+
+ if (last_ir != ir && ir) {
+ int j;
+
+ for (j = 0; j < indent; j++) {
+ fprintf(stdout, " ");
+ }
+ ir->print();
+ printf("\n");
+ last_ir = ir;
+
+ fprintf(stdout, " "); /* line number spacing. */
+ }
+
+ indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
+ PROG_PRINT_DEBUG, NULL);
+ }
+}
+
+static void
+count_resources(struct gl_program *prog)
+{
+ unsigned int i;
+
+ prog->SamplersUsed = 0;
+
+ for (i = 0; i < prog->NumInstructions; i++) {
+ struct prog_instruction *inst = &prog->Instructions[i];
+
+ if (_mesa_is_tex_instruction(inst->Opcode)) {
+ prog->SamplerTargets[inst->TexSrcUnit] =
+ (gl_texture_index)inst->TexSrcTarget;
+ prog->SamplersUsed |= 1 << inst->TexSrcUnit;
+ if (inst->TexShadow) {
+ prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
+ }
+ }
+ }
+
+ _mesa_update_shader_textures_used(prog);
+}
+
+struct uniform_sort {
+ struct gl_uniform *u;
+ int pos;
+};
+
+/* The shader_program->Uniforms list is almost sorted in increasing
+ * uniform->{Frag,Vert}Pos locations, but not quite when there are
+ * uniforms shared between targets. We need to add parameters in
+ * increasing order for the targets.
+ */
+static int
+sort_uniforms(const void *a, const void *b)
+{
+ struct uniform_sort *u1 = (struct uniform_sort *)a;
+ struct uniform_sort *u2 = (struct uniform_sort *)b;
+
+ return u1->pos - u2->pos;
+}
+
+/* Add the uniforms to the parameters. The linker chose locations
+ * in our parameters lists (which weren't created yet), which the
+ * uniforms code will use to poke values into our parameters list
+ * when uniforms are updated.
+ */
+static void
+add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
+ struct gl_shader *shader,
+ struct gl_program *prog)
+{
+ unsigned int i;
+ unsigned int next_sampler = 0, num_uniforms = 0;
+ struct uniform_sort *sorted_uniforms;
+
+ sorted_uniforms = talloc_array(NULL, struct uniform_sort,
+ shader_program->Uniforms->NumUniforms);
+
+ for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) {
+ struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i;
+ int parameter_index = -1;
+
+ switch (shader->Type) {
+ case GL_VERTEX_SHADER:
+ parameter_index = uniform->VertPos;
+ break;
+ case GL_FRAGMENT_SHADER:
+ parameter_index = uniform->FragPos;
+ break;
+ case GL_GEOMETRY_SHADER:
+ parameter_index = uniform->GeomPos;
+ break;
+ }
+
+ /* Only add uniforms used in our target. */
+ if (parameter_index != -1) {
+ sorted_uniforms[num_uniforms].pos = parameter_index;
+ sorted_uniforms[num_uniforms].u = uniform;
+ num_uniforms++;
+ }
+ }
+
+ qsort(sorted_uniforms, num_uniforms, sizeof(struct uniform_sort),
+ sort_uniforms);
+
+ for (i = 0; i < num_uniforms; i++) {
+ struct gl_uniform *uniform = sorted_uniforms[i].u;
+ int parameter_index = sorted_uniforms[i].pos;
+ const glsl_type *type = uniform->Type;
+ unsigned int size;
+
+ if (type->is_vector() ||
+ type->is_scalar()) {
+ size = type->vector_elements;
+ } else {
+ size = type_size(type) * 4;
+ }
+
+ gl_register_file file;
+ if (type->is_sampler() ||
+ (type->is_array() && type->fields.array->is_sampler())) {
+ file = PROGRAM_SAMPLER;
+ } else {
+ file = PROGRAM_UNIFORM;
+ }
+
+ GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
+ uniform->Name);
+
+ if (index < 0) {
+ index = _mesa_add_parameter(prog->Parameters, file,
+ uniform->Name, size, type->gl_type,
+ NULL, NULL, 0x0);
+
+ /* Sampler uniform values are stored in prog->SamplerUnits,
+ * and the entry in that array is selected by this index we
+ * store in ParameterValues[].
+ */
+ if (file == PROGRAM_SAMPLER) {
+ for (unsigned int j = 0; j < size / 4; j++)
+ prog->Parameters->ParameterValues[index + j][0] = next_sampler++;
+ }
+
+ /* The location chosen in the Parameters list here (returned
+ * from _mesa_add_uniform) has to match what the linker chose.
+ */
+ if (index != parameter_index) {
+ fail_link(shader_program, "Allocation of uniform `%s' to target "
+ "failed (%d vs %d)\n",
+ uniform->Name, index, parameter_index);
+ }
+ }
+ }
+
+ talloc_free(sorted_uniforms);
+}
+
+static void
+set_uniform_initializer(GLcontext *ctx, void *mem_ctx,
+ struct gl_shader_program *shader_program,
+ const char *name, const glsl_type *type,
+ ir_constant *val)
+{
+ if (type->is_record()) {
+ ir_constant *field_constant;
+
+ field_constant = (ir_constant *)val->components.get_head();
+
+ for (unsigned int i = 0; i < type->length; i++) {
+ const glsl_type *field_type = type->fields.structure[i].type;
+ const char *field_name = talloc_asprintf(mem_ctx, "%s.%s", name,
+ type->fields.structure[i].name);
+ set_uniform_initializer(ctx, mem_ctx, shader_program, field_name,
+ field_type, field_constant);
+ field_constant = (ir_constant *)field_constant->next;
+ }
+ return;
+ }
+
+ int loc = _mesa_get_uniform_location(ctx, shader_program, name);
+
+ if (loc == -1) {
+ fail_link(shader_program,
+ "Couldn't find uniform for initializer %s\n", name);
+ return;
+ }
+
+ for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) {
+ ir_constant *element;
+ const glsl_type *element_type;
+ if (type->is_array()) {
+ element = val->array_elements[i];
+ element_type = type->fields.array;
+ } else {
+ element = val;
+ element_type = type;
+ }
+
+ void *values;
+
+ if (element_type->base_type == GLSL_TYPE_BOOL) {
+ int *conv = talloc_array(mem_ctx, int, element_type->components());
+ for (unsigned int j = 0; j < element_type->components(); j++) {
+ conv[j] = element->value.b[j];
+ }
+ values = (void *)conv;
+ element_type = glsl_type::get_instance(GLSL_TYPE_INT,
+ element_type->vector_elements,
+ 1);
+ } else {
+ values = &element->value;
+ }
+
+ if (element_type->is_matrix()) {
+ _mesa_uniform_matrix(ctx, shader_program,
+ element_type->matrix_columns,
+ element_type->vector_elements,
+ loc, 1, GL_FALSE, (GLfloat *)values);
+ loc += element_type->matrix_columns;
+ } else {
+ _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns,
+ values, element_type->gl_type);
+ loc += type_size(element_type);
+ }
+ }
+}
+
+static void
+set_uniform_initializers(GLcontext *ctx,
+ struct gl_shader_program *shader_program)
+{
+ void *mem_ctx = NULL;
+
+ for (unsigned int i = 0; i < shader_program->_NumLinkedShaders; i++) {
+ struct gl_shader *shader = shader_program->_LinkedShaders[i];
+ foreach_iter(exec_list_iterator, iter, *shader->ir) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_variable *var = ir->as_variable();
+
+ if (!var || var->mode != ir_var_uniform || !var->constant_value)
+ continue;
+
+ if (!mem_ctx)
+ mem_ctx = talloc_new(NULL);
+
+ set_uniform_initializer(ctx, mem_ctx, shader_program, var->name,
+ var->type, var->constant_value);
+ }
+ }
+
+ talloc_free(mem_ctx);
+}
+
+struct gl_program *
+get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
+ struct gl_shader *shader)
+{
+ ir_to_mesa_visitor v;
+ struct prog_instruction *mesa_instructions, *mesa_inst;
+ ir_instruction **mesa_instruction_annotation;
+ int i;
+ struct gl_program *prog;
+ GLenum target;
+ const char *target_string;
+ GLboolean progress;
+
+ switch (shader->Type) {
+ case GL_VERTEX_SHADER:
+ target = GL_VERTEX_PROGRAM_ARB;
+ target_string = "vertex";
+ break;
+ case GL_FRAGMENT_SHADER:
+ target = GL_FRAGMENT_PROGRAM_ARB;
+ target_string = "fragment";
+ break;
+ default:
+ assert(!"should not be reached");
+ return NULL;
+ }
+
+ validate_ir_tree(shader->ir);
+
+ prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name);
+ if (!prog)
+ return NULL;
+ prog->Parameters = _mesa_new_parameter_list();
+ prog->Varying = _mesa_new_parameter_list();
+ prog->Attributes = _mesa_new_parameter_list();
+ v.ctx = ctx;
+ v.prog = prog;
+ v.shader_program = shader_program;
+
+ add_uniforms_to_parameters_list(shader_program, shader, prog);
+
+ /* Emit Mesa IR for main(). */
+ visit_exec_list(shader->ir, &v);
+ v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
+
+ /* Now emit bodies for any functions that were used. */
+ do {
+ progress = GL_FALSE;
+
+ foreach_iter(exec_list_iterator, iter, v.function_signatures) {
+ function_entry *entry = (function_entry *)iter.get();
+
+ if (!entry->bgn_inst) {
+ v.current_function = entry;
+
+ entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB);
+ entry->bgn_inst->function = entry;
+
+ visit_exec_list(&entry->sig->body, &v);
+
+ ir_to_mesa_instruction *last;
+ last = (ir_to_mesa_instruction *)v.instructions.get_tail();
+ if (last->op != OPCODE_RET)
+ v.ir_to_mesa_emit_op0(NULL, OPCODE_RET);
+
+ ir_to_mesa_instruction *end;
+ end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB);
+ end->function = entry;
+
+ progress = GL_TRUE;
+ }
+ }
+ } while (progress);
+
+ prog->NumTemporaries = v.next_temp;
+
+ int num_instructions = 0;
+ foreach_iter(exec_list_iterator, iter, v.instructions) {
+ num_instructions++;
+ }
+
+ mesa_instructions =
+ (struct prog_instruction *)calloc(num_instructions,
+ sizeof(*mesa_instructions));
+ mesa_instruction_annotation = talloc_array(v.mem_ctx, ir_instruction *,
+ num_instructions);
+
+ mesa_inst = mesa_instructions;
+ i = 0;
+ foreach_iter(exec_list_iterator, iter, v.instructions) {
+ ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
+
+ mesa_inst->Opcode = inst->op;
+ mesa_inst->CondUpdate = inst->cond_update;
+ mesa_inst->DstReg.File = inst->dst_reg.file;
+ mesa_inst->DstReg.Index = inst->dst_reg.index;
+ mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
+ mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
+ mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL;
+ mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
+ mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
+ mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
+ mesa_inst->TexSrcUnit = inst->sampler;
+ mesa_inst->TexSrcTarget = inst->tex_target;
+ mesa_inst->TexShadow = inst->tex_shadow;
+ mesa_instruction_annotation[i] = inst->ir;
+
+ /* Set IndirectRegisterFiles. */
+ if (mesa_inst->DstReg.RelAddr)
+ prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File;
+
+ for (unsigned src = 0; src < 3; src++)
+ if (mesa_inst->SrcReg[src].RelAddr)
+ prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File;
+
+ if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
+ fail_link(shader_program, "Couldn't flatten if statement\n");
+ }
+
+ switch (mesa_inst->Opcode) {
+ case OPCODE_BGNSUB:
+ inst->function->inst = i;
+ mesa_inst->Comment = strdup(inst->function->sig->function_name());
+ break;
+ case OPCODE_ENDSUB:
+ mesa_inst->Comment = strdup(inst->function->sig->function_name());
+ break;
+ case OPCODE_CAL:
+ mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */
+ break;
+ case OPCODE_ARL:
+ prog->NumAddressRegs = 1;
+ break;
+ default:
+ break;
+ }
+
+ mesa_inst++;
+ i++;
+ }
+
+ set_branchtargets(&v, mesa_instructions, num_instructions);
+
+ if (ctx->Shader.Flags & GLSL_DUMP) {
+ printf("\n");
+ printf("GLSL IR for linked %s program %d:\n", target_string,
+ shader_program->Name);
+ _mesa_print_ir(shader->ir, NULL);
+ printf("\n");
+ printf("\n");
+ printf("Mesa IR for linked %s program %d:\n", target_string,
+ shader_program->Name);
+ print_program(mesa_instructions, mesa_instruction_annotation,
+ num_instructions);
+ }
+
+ prog->Instructions = mesa_instructions;
+ prog->NumInstructions = num_instructions;
+
+ do_set_program_inouts(shader->ir, prog);
+ count_resources(prog);
+
+ _mesa_reference_program(ctx, &shader->Program, prog);
+
+ if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
+ _mesa_optimize_program(ctx, prog);
+ }
+
+ return prog;
+}
+
+extern "C" {
+GLboolean
+_mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader)
+{
+ assert(shader->CompileStatus);
+ (void) ctx;
+
+ return GL_TRUE;
+}
+
+GLboolean
+_mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
+{
+ assert(prog->LinkStatus);
+
+ for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
+ bool progress;
+ exec_list *ir = prog->_LinkedShaders[i]->ir;
+
+ do {
+ progress = false;
+
+ /* Lowering */
+ do_mat_op_to_vec(ir);
+ do_mod_to_fract(ir);
+ do_div_to_mul_rcp(ir);
+ do_explog_to_explog2(ir);
+
+ progress = do_common_optimization(ir, true) || progress;
+
+ if (ctx->Shader.EmitNoIfs)
+ progress = do_if_to_cond_assign(ir) || progress;
+
+ progress = do_vec_index_to_cond_assign(ir) || progress;
+ } while (progress);
+
+ validate_ir_tree(ir);
+ }
+
+ for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
+ struct gl_program *linked_prog;
+ bool ok = true;
+
+ linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
+
+ switch (prog->_LinkedShaders[i]->Type) {
+ case GL_VERTEX_SHADER:
+ _mesa_reference_vertprog(ctx, &prog->VertexProgram,
+ (struct gl_vertex_program *)linked_prog);
+ ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
+ linked_prog);
+ break;
+ case GL_FRAGMENT_SHADER:
+ _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
+ (struct gl_fragment_program *)linked_prog);
+ ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ linked_prog);
+ break;
+ }
+ if (!ok) {
+ return GL_FALSE;
+ }
+ _mesa_reference_program(ctx, &linked_prog, NULL);
+ }
+
+ return GL_TRUE;
+}
+
+void
+_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
+{
+ struct _mesa_glsl_parse_state *state =
+ new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
+
+ const char *source = shader->Source;
+ state->error = preprocess(state, &source, &state->info_log,
+ &ctx->Extensions);
+
+ if (ctx->Shader.Flags & GLSL_DUMP) {
+ printf("GLSL source for shader %d:\n", shader->Name);
+ printf("%s\n", shader->Source);
+ }
+
+ if (!state->error) {
+ _mesa_glsl_lexer_ctor(state, source);
+ _mesa_glsl_parse(state);
+ _mesa_glsl_lexer_dtor(state);
+ }
+
+ talloc_free(shader->ir);
+ shader->ir = new(shader) exec_list;
+ if (!state->error && !state->translation_unit.is_empty())
+ _mesa_ast_to_hir(shader->ir, state);
+
+ if (!state->error && !shader->ir->is_empty()) {
+ validate_ir_tree(shader->ir);
+
+ /* Do some optimization at compile time to reduce shader IR size
+ * and reduce later work if the same shader is linked multiple times
+ */
+ while (do_common_optimization(shader->ir, false))
+ ;
+
+ validate_ir_tree(shader->ir);
+ }
+
+ shader->symbols = state->symbols;
+
+ shader->CompileStatus = !state->error;
+ shader->InfoLog = state->info_log;
+ shader->Version = state->language_version;
+ memcpy(shader->builtins_to_link, state->builtins_to_link,
+ sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
+ shader->num_builtins_to_link = state->num_builtins_to_link;
+
+ if (ctx->Shader.Flags & GLSL_LOG) {
+ _mesa_write_shader_to_file(shader);
+ }
+
+ if (ctx->Shader.Flags & GLSL_DUMP) {
+ if (shader->CompileStatus) {
+ printf("GLSL IR for shader %d:\n", shader->Name);
+ _mesa_print_ir(shader->ir, NULL);
+ printf("\n\n");
+ } else {
+ printf("GLSL shader %d failed to compile.\n", shader->Name);
+ }
+ if (shader->InfoLog && shader->InfoLog[0] != 0) {
+ printf("GLSL shader %d info log:\n", shader->Name);
+ printf("%s\n", shader->InfoLog);
+ }
+ }
+
+ /* Retain any live IR, but trash the rest. */
+ reparent_ir(shader->ir, shader->ir);
+
+ talloc_free(state);
+
+ if (shader->CompileStatus) {
+ if (!ctx->Driver.CompileShader(ctx, shader))
+ shader->CompileStatus = GL_FALSE;
+ }
+}
+
+void
+_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
+{
+ unsigned int i;
+
+ _mesa_clear_shader_program_data(ctx, prog);
+
+ prog->LinkStatus = GL_TRUE;
+
+ for (i = 0; i < prog->NumShaders; i++) {
+ if (!prog->Shaders[i]->CompileStatus) {
+ fail_link(prog, "linking with uncompiled shader");
+ prog->LinkStatus = GL_FALSE;
+ }
+ }
+
+ prog->Varying = _mesa_new_parameter_list();
+ _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
+ _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
+
+ if (prog->LinkStatus) {
+ link_shaders(ctx, prog);
+ }
+
+ if (prog->LinkStatus) {
+ if (!ctx->Driver.LinkShader(ctx, prog)) {
+ prog->LinkStatus = GL_FALSE;
+ }
+ }
+
+ set_uniform_initializers(ctx, prog);
+
+ if (ctx->Shader.Flags & GLSL_DUMP) {
+ if (!prog->LinkStatus) {
+ printf("GLSL shader program %d failed to link\n", prog->Name);
+ }
+
+ if (prog->InfoLog && prog->InfoLog[0] != 0) {
+ printf("GLSL shader program %d info log:\n", prog->Name);
+ printf("%s\n", prog->InfoLog);
+ }
+ }
+}
+
+} /* extern "C" */
diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h
new file mode 100644
index 00000000000..ecaacde4bb0
--- /dev/null
+++ b/src/mesa/program/ir_to_mesa.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "main/config.h"
+#include "main/mtypes.h"
+
+void _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *sh);
+void _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog);
+GLboolean _mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader);
+GLboolean _mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.c
index 1670c91b6ad..2ae5bc572af 100644
--- a/src/mesa/program/prog_execute.c
+++ b/src/mesa/program/prog_execute.c
@@ -771,6 +771,13 @@ _mesa_execute_program(GLcontext * ctx,
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);
+ if (DEBUG_PROG) {
+ printf("CMP (%g %g %g %g) = (%g %g %g %g) < 0 ? (%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_COS:
@@ -1679,6 +1686,22 @@ _mesa_execute_program(GLcontext * ctx,
store_vector4(inst, machine, color);
}
break;
+ case OPCODE_TXL:
+ /* Texel lookup with explicit LOD */
+ {
+ GLfloat texcoord[4], color[4], lod;
+
+ fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+
+ /* texcoord[3] is the LOD */
+ lod = texcoord[3];
+
+ machine->FetchTexelLod(ctx, texcoord, lod,
+ machine->Samplers[inst->TexSrcUnit], color);
+
+ store_vector4(inst, machine, color);
+ }
+ break;
case OPCODE_TXP: /* GL_ARB_fragment_program only */
/* Texture lookup w/ projective divide */
{
@@ -1842,7 +1865,11 @@ _mesa_execute_program(GLcontext * ctx,
numExec++;
if (numExec > maxExec) {
- _mesa_problem(ctx, "Infinite loop detected in fragment program");
+ static GLboolean reported = GL_FALSE;
+ if (!reported) {
+ _mesa_problem(ctx, "Infinite loop detected in fragment program");
+ reported = GL_TRUE;
+ }
return GL_TRUE;
}
diff --git a/src/mesa/program/prog_instruction.h b/src/mesa/program/prog_instruction.h
index 098b366ab56..ca90de7ce1c 100644
--- a/src/mesa/program/prog_instruction.h
+++ b/src/mesa/program/prog_instruction.h
@@ -401,7 +401,7 @@ struct prog_instruction
/**
* 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 BRK, points to ENDLOOP
* For IF, points to ELSE or ENDIF.
* For ELSE, points to ENDIF.
*/
diff --git a/src/mesa/program/prog_optimize.c b/src/mesa/program/prog_optimize.c
index c78187c983d..0dc779073db 100644
--- a/src/mesa/program/prog_optimize.c
+++ b/src/mesa/program/prog_optimize.c
@@ -34,7 +34,12 @@
#define MAX_LOOP_NESTING 50
-
+/* MAX_PROGRAM_TEMPS is a low number (256), and we want to be able to
+ * register allocate many temporary values into that small number of
+ * temps. So allow large temporary indices coming into the register
+ * allocator.
+ */
+#define REG_ALLOCATE_MAX_PROGRAM_TEMPS ((1 << INST_INDEX_BITS) - 1)
static GLboolean dbg = GL_FALSE;
@@ -233,7 +238,7 @@ replace_regs(struct gl_program *prog, gl_register_file file, const GLint map[])
static GLboolean
_mesa_remove_dead_code_global(struct gl_program *prog)
{
- GLboolean tempRead[MAX_PROGRAM_TEMPS][4];
+ GLboolean tempRead[REG_ALLOCATE_MAX_PROGRAM_TEMPS][4];
GLboolean *removeInst; /* per-instruction removal flag */
GLuint i, rem = 0, comp;
@@ -258,7 +263,7 @@ _mesa_remove_dead_code_global(struct gl_program *prog)
if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
const GLuint index = inst->SrcReg[j].Index;
GLuint read_mask;
- ASSERT(index < MAX_PROGRAM_TEMPS);
+ ASSERT(index < REG_ALLOCATE_MAX_PROGRAM_TEMPS);
read_mask = get_src_arg_mask(inst, j, NO_MASK);
if (inst->SrcReg[j].RelAddr) {
@@ -281,7 +286,7 @@ _mesa_remove_dead_code_global(struct gl_program *prog)
/* check dst reg */
if (inst->DstReg.File == PROGRAM_TEMPORARY) {
const GLuint index = inst->DstReg.Index;
- ASSERT(index < MAX_PROGRAM_TEMPS);
+ ASSERT(index < REG_ALLOCATE_MAX_PROGRAM_TEMPS);
if (inst->DstReg.RelAddr) {
if (dbg)
@@ -753,7 +758,11 @@ _mesa_remove_extra_moves(struct gl_program *prog)
nesting--;
break;
case OPCODE_MOV:
- if (i > 0 && can_downward_mov_be_modifed(mov) && nesting == 0) {
+ if (i > 0 &&
+ can_downward_mov_be_modifed(mov) &&
+ mov->SrcReg[0].File == PROGRAM_TEMPORARY &&
+ nesting == 0)
+ {
/* see if this MOV can be removed */
const GLuint id = mov->SrcReg[0].Index;
@@ -826,7 +835,7 @@ struct interval
struct interval_list
{
GLuint Num;
- struct interval Intervals[MAX_PROGRAM_TEMPS];
+ struct interval Intervals[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
};
@@ -913,15 +922,33 @@ sort_interval_list_by_start(struct interval_list *list)
#endif
}
+struct loop_info
+{
+ GLuint Start, End; /**< Start, end instructions of loop */
+};
/**
* Update the intermediate interval info for register 'index' and
* instruction 'ic'.
*/
static void
-update_interval(GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic)
+update_interval(GLint intBegin[], GLint intEnd[],
+ struct loop_info *loopStack, GLuint loopStackDepth,
+ GLuint index, GLuint ic)
{
- ASSERT(index < MAX_PROGRAM_TEMPS);
+ int i;
+
+ /* If the register is used in a loop, extend its lifetime through the end
+ * of the outermost loop that doesn't contain its definition.
+ */
+ for (i = 0; i < loopStackDepth; i++) {
+ if (intBegin[index] < loopStack[i].Start) {
+ ic = loopStack[i].End;
+ break;
+ }
+ }
+
+ ASSERT(index < REG_ALLOCATE_MAX_PROGRAM_TEMPS);
if (intBegin[index] == -1) {
ASSERT(intEnd[index] == -1);
intBegin[index] = intEnd[index] = ic;
@@ -938,18 +965,14 @@ update_interval(GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic)
GLboolean
_mesa_find_temp_intervals(const struct prog_instruction *instructions,
GLuint numInstructions,
- GLint intBegin[MAX_PROGRAM_TEMPS],
- GLint intEnd[MAX_PROGRAM_TEMPS])
+ GLint intBegin[REG_ALLOCATE_MAX_PROGRAM_TEMPS],
+ GLint intEnd[REG_ALLOCATE_MAX_PROGRAM_TEMPS])
{
- struct loop_info
- {
- GLuint Start, End; /**< Start, end instructions of loop */
- };
struct loop_info loopStack[MAX_LOOP_NESTING];
GLuint loopStackDepth = 0;
GLuint i;
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
+ for (i = 0; i < REG_ALLOCATE_MAX_PROGRAM_TEMPS; i++){
intBegin[i] = intEnd[i] = -1;
}
@@ -975,24 +998,16 @@ _mesa_find_temp_intervals(const struct prog_instruction *instructions,
const GLuint index = inst->SrcReg[j].Index;
if (inst->SrcReg[j].RelAddr)
return GL_FALSE;
- update_interval(intBegin, intEnd, index, i);
- if (loopStackDepth > 0) {
- /* extend temp register's interval to end of loop */
- GLuint loopEnd = loopStack[loopStackDepth - 1].End;
- update_interval(intBegin, intEnd, index, loopEnd);
- }
+ update_interval(intBegin, intEnd, loopStack, loopStackDepth,
+ index, i);
}
}
if (inst->DstReg.File == PROGRAM_TEMPORARY) {
const GLuint index = inst->DstReg.Index;
if (inst->DstReg.RelAddr)
return GL_FALSE;
- update_interval(intBegin, intEnd, index, i);
- if (loopStackDepth > 0) {
- /* extend temp register's interval to end of loop */
- GLuint loopEnd = loopStack[loopStackDepth - 1].End;
- update_interval(intBegin, intEnd, index, loopEnd);
- }
+ update_interval(intBegin, intEnd, loopStack, loopStackDepth,
+ index, i);
}
}
}
@@ -1012,7 +1027,8 @@ static GLboolean
find_live_intervals(struct gl_program *prog,
struct interval_list *liveIntervals)
{
- GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
+ GLint intBegin[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
+ GLint intEnd[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
GLuint i;
/*
@@ -1032,7 +1048,7 @@ find_live_intervals(struct gl_program *prog,
/* Build live intervals list from intermediate arrays */
liveIntervals->Num = 0;
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+ for (i = 0; i < REG_ALLOCATE_MAX_PROGRAM_TEMPS; i++) {
if (intBegin[i] >= 0) {
struct interval inv;
inv.Reg = i;
@@ -1068,10 +1084,10 @@ find_live_intervals(struct gl_program *prog,
/** Scan the array of used register flags to find free entry */
static GLint
-alloc_register(GLboolean usedRegs[MAX_PROGRAM_TEMPS])
+alloc_register(GLboolean usedRegs[REG_ALLOCATE_MAX_PROGRAM_TEMPS])
{
GLuint k;
- for (k = 0; k < MAX_PROGRAM_TEMPS; k++) {
+ for (k = 0; k < REG_ALLOCATE_MAX_PROGRAM_TEMPS; k++) {
if (!usedRegs[k]) {
usedRegs[k] = GL_TRUE;
return k;
@@ -1093,8 +1109,8 @@ static void
_mesa_reallocate_registers(struct gl_program *prog)
{
struct interval_list liveIntervals;
- GLint registerMap[MAX_PROGRAM_TEMPS];
- GLboolean usedRegs[MAX_PROGRAM_TEMPS];
+ GLint registerMap[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
+ GLboolean usedRegs[REG_ALLOCATE_MAX_PROGRAM_TEMPS];
GLuint i;
GLint maxTemp = -1;
@@ -1103,7 +1119,7 @@ _mesa_reallocate_registers(struct gl_program *prog)
_mesa_print_program(prog);
}
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
+ for (i = 0; i < REG_ALLOCATE_MAX_PROGRAM_TEMPS; i++){
registerMap[i] = -1;
usedRegs[i] = GL_FALSE;
}
diff --git a/src/mesa/program/prog_parameter.c b/src/mesa/program/prog_parameter.c
index aac488c79ab..6bf8a081b02 100644
--- a/src/mesa/program/prog_parameter.c
+++ b/src/mesa/program/prog_parameter.c
@@ -284,93 +284,6 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
return pos;
}
-
-/**
- * Add a uniform to the parameter list.
- * Note that if the uniform is an array, size may be greater than
- * what's implied by the datatype.
- * \param name uniform's name
- * \param size number of floats to allocate
- * \param datatype GL_FLOAT_VEC3, GL_FLOAT_MAT4, etc.
- */
-GLint
-_mesa_add_uniform(struct gl_program_parameter_list *paramList,
- const char *name, GLuint size, GLenum datatype,
- const GLfloat *values)
-{
- GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
- ASSERT(datatype != GL_NONE);
- if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) {
- ASSERT(paramList->Parameters[i].Size == size);
- ASSERT(paramList->Parameters[i].DataType == datatype);
- /* already in list */
- return i;
- }
- else {
- i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name,
- size, datatype, values, NULL, 0x0);
- return i;
- }
-}
-
-
-/**
- * Mark the named uniform as 'used'.
- */
-void
-_mesa_use_uniform(struct gl_program_parameter_list *paramList,
- const char *name)
-{
- GLuint i;
- for (i = 0; i < paramList->NumParameters; i++) {
- struct gl_program_parameter *p = paramList->Parameters + i;
- if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) &&
- strcmp(p->Name, name) == 0) {
- p->Used = GL_TRUE;
- /* Note that large uniforms may occupy several slots so we're
- * not done searching yet.
- */
- }
- }
-}
-
-
-/**
- * Add a sampler to the parameter list.
- * \param name uniform's name
- * \param datatype GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
- * \param index the sampler number (as seen in TEX instructions)
- * \return sampler index (starting at zero) or -1 if error
- */
-GLint
-_mesa_add_sampler(struct gl_program_parameter_list *paramList,
- const char *name, GLenum datatype)
-{
- GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
- if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
- ASSERT(paramList->Parameters[i].Size == 1);
- ASSERT(paramList->Parameters[i].DataType == datatype);
- /* already in list */
- return (GLint) paramList->ParameterValues[i][0];
- }
- else {
- GLuint i;
- const GLint size = 1; /* a sampler is basically a texture unit number */
- GLfloat value[4];
- GLint numSamplers = 0;
- for (i = 0; i < paramList->NumParameters; i++) {
- if (paramList->Parameters[i].Type == PROGRAM_SAMPLER)
- numSamplers++;
- }
- value[0] = (GLfloat) numSamplers;
- value[1] = value[2] = value[3] = 0.0F;
- (void) _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
- size, datatype, value, NULL, 0x0);
- return numSamplers;
- }
-}
-
-
/**
* Add parameter representing a varying variable.
*/
@@ -569,8 +482,10 @@ _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
assert(vSize >= 1);
assert(vSize <= 4);
- if (!list)
- return -1;
+ if (!list) {
+ *posOut = -1;
+ return GL_FALSE;
+ }
for (i = 0; i < list->NumParameters; i++) {
if (list->Parameters[i].Type == PROGRAM_CONSTANT) {
@@ -591,7 +506,7 @@ _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
if (vSize == 1) {
/* look for v[0] anywhere within float[4] value */
GLuint j;
- for (j = 0; j < 4; j++) {
+ for (j = 0; j < list->Parameters[i].Size; j++) {
if (list->ParameterValues[i][j] == v[0]) {
/* found it */
*posOut = i;
@@ -657,7 +572,6 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
list->ParameterValues[i], NULL, 0x0);
ASSERT(j >= 0);
pCopy = clone->Parameters + j;
- pCopy->Used = p->Used;
pCopy->Flags = p->Flags;
/* copy state indexes */
if (p->Type == PROGRAM_STATE_VAR) {
diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h
index cc3378ae201..10cbbe57a6c 100644
--- a/src/mesa/program/prog_parameter.h
+++ b/src/mesa/program/prog_parameter.h
@@ -64,8 +64,7 @@ struct gl_program_parameter
* The next program parameter's Size will be Size-4 of this parameter.
*/
GLuint Size;
- GLboolean Used; /**< Helper flag for GLSL uniform tracking */
- GLboolean Initialized; /**< Has the ParameterValue[] been set? */
+ GLboolean Initialized; /**< debug: Has the ParameterValue[] been set? */
GLbitfield Flags; /**< Bitmask of PROG_PARAM_*_BIT */
/**
* A sequence of STATE_* tokens and integers to identify GL state.
@@ -132,19 +131,6 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
GLuint *swizzleOut);
extern GLint
-_mesa_add_uniform(struct gl_program_parameter_list *paramList,
- const char *name, GLuint size, GLenum datatype,
- const GLfloat *values);
-
-extern void
-_mesa_use_uniform(struct gl_program_parameter_list *paramList,
- const char *name);
-
-extern GLint
-_mesa_add_sampler(struct gl_program_parameter_list *paramList,
- const char *name, GLenum datatype);
-
-extern GLint
_mesa_add_varying(struct gl_program_parameter_list *paramList,
const char *name, GLuint size, GLenum datatype,
GLbitfield flags);
diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.c
index 6056c459e4c..00aa6de963b 100644
--- a/src/mesa/program/prog_print.c
+++ b/src/mesa/program/prog_print.c
@@ -540,12 +540,12 @@ fprint_comment(FILE *f, const struct prog_instruction *inst)
}
-static void
-fprint_alu_instruction(FILE *f,
- const struct prog_instruction *inst,
- const char *opcode_string, GLuint numRegs,
- gl_prog_print_mode mode,
- const struct gl_program *prog)
+void
+_mesa_fprint_alu_instruction(FILE *f,
+ const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog)
{
GLuint j;
@@ -582,8 +582,8 @@ void
_mesa_print_alu_instruction(const struct prog_instruction *inst,
const char *opcode_string, GLuint numRegs)
{
- fprint_alu_instruction(stderr, inst, opcode_string,
- numRegs, PROG_PRINT_DEBUG, NULL);
+ _mesa_fprint_alu_instruction(stderr, inst, opcode_string,
+ numRegs, PROG_PRINT_DEBUG, NULL);
}
@@ -791,16 +791,16 @@ _mesa_fprint_instruction_opt(FILE *f,
default:
if (inst->Opcode < MAX_OPCODE) {
/* typical alu instruction */
- fprint_alu_instruction(f, inst,
- _mesa_opcode_string(inst->Opcode),
- _mesa_num_inst_src_regs(inst->Opcode),
- mode, prog);
+ _mesa_fprint_alu_instruction(f, inst,
+ _mesa_opcode_string(inst->Opcode),
+ _mesa_num_inst_src_regs(inst->Opcode),
+ mode, prog);
}
else {
- fprint_alu_instruction(f, inst,
- _mesa_opcode_string(inst->Opcode),
- 3/*_mesa_num_inst_src_regs(inst->Opcode)*/,
- mode, prog);
+ _mesa_fprint_alu_instruction(f, inst,
+ _mesa_opcode_string(inst->Opcode),
+ 3/*_mesa_num_inst_src_regs(inst->Opcode)*/,
+ mode, prog);
}
break;
}
@@ -1033,11 +1033,11 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
fprintf(f, "/* Compile status: %s */\n",
shader->CompileStatus ? "ok" : "fail");
- if (!shader->CompileStatus) {
- fprintf(f, "/* Log Info: */\n");
+ fprintf(f, "/* Log Info: */\n");
+ if (shader->InfoLog) {
fputs(shader->InfoLog, f);
}
- else {
+ if (shader->CompileStatus && shader->Program) {
fprintf(f, "/* GPU code */\n");
fprintf(f, "/*\n");
_mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
diff --git a/src/mesa/program/prog_print.h b/src/mesa/program/prog_print.h
index 4667373f379..78b90aeb4d6 100644
--- a/src/mesa/program/prog_print.h
+++ b/src/mesa/program/prog_print.h
@@ -66,6 +66,13 @@ extern void
_mesa_print_swizzle(GLuint swizzle);
extern void
+_mesa_fprint_alu_instruction(FILE *f,
+ const struct prog_instruction *inst,
+ const char *opcode_string, GLuint numRegs,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog);
+
+extern void
_mesa_print_alu_instruction(const struct prog_instruction *inst,
const char *opcode_string, GLuint numRegs);
diff --git a/src/mesa/program/prog_uniform.c b/src/mesa/program/prog_uniform.c
index 5aa9878d43c..28acb8871a7 100644
--- a/src/mesa/program/prog_uniform.c
+++ b/src/mesa/program/prog_uniform.c
@@ -44,6 +44,10 @@ void
_mesa_free_uniform_list(struct gl_uniform_list *list)
{
GLuint i;
+
+ if (!list)
+ return;
+
for (i = 0; i < list->NumUniforms; i++) {
free((void *) list->Uniforms[i].Name);
}
diff --git a/src/mesa/program/prog_uniform.h b/src/mesa/program/prog_uniform.h
index 7988d534a7d..67f78006eac 100644
--- a/src/mesa/program/prog_uniform.h
+++ b/src/mesa/program/prog_uniform.h
@@ -51,10 +51,7 @@ struct gl_uniform
GLint FragPos;
GLint GeomPos;
GLboolean Initialized; /**< For debug. Has this uniform been set? */
-#if 0
- GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
- GLuint Size; /**< Number of components (1..4) */
-#endif
+ const struct glsl_type *Type;
};
diff --git a/src/mesa/program/symbol_table.c b/src/mesa/program/symbol_table.c
index 6a5d6868974..09e7cb44ef3 100644
--- a/src/mesa/program/symbol_table.c
+++ b/src/mesa/program/symbol_table.c
@@ -58,7 +58,9 @@ struct symbol {
*/
int name_space;
-
+ /** Scope depth where this symbol was defined. */
+ unsigned depth;
+
/**
* Arbitrary user supplied data.
*/
@@ -73,7 +75,7 @@ struct symbol_header {
struct symbol_header *next;
/** Symbol name. */
- const char *name;
+ char *name;
/** Linked list of symbols with the same name. */
struct symbol *symbols;
@@ -104,6 +106,9 @@ struct _mesa_symbol_table {
/** List of all symbol headers in the table. */
struct symbol_header *hdr;
+
+ /** Current scope depth. */
+ unsigned depth;
};
@@ -157,6 +162,7 @@ _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
struct symbol *sym = scope->symbols;
table->current_scope = scope->next;
+ table->depth--;
free(scope);
@@ -184,6 +190,7 @@ _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
scope->next = table->current_scope;
table->current_scope = scope;
+ table->depth++;
}
@@ -261,6 +268,36 @@ _mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
}
+/**
+ * Determine the scope "distance" of a symbol from the current scope
+ *
+ * \return
+ * A non-negative number for the number of scopes between the current scope
+ * and the scope where a symbol was defined. A value of zero means the current
+ * scope. A negative number if the symbol does not exist.
+ */
+int
+_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct symbol_header *const hdr = find_symbol(table, name);
+ struct symbol *sym;
+
+ if (hdr != NULL) {
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ assert(sym->depth <= table->depth);
+ return sym->depth - table->depth;
+ }
+ }
+ }
+
+ return -1;
+}
+
+
void *
_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
int name_space, const char *name)
@@ -300,21 +337,34 @@ _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
if (hdr == NULL) {
hdr = calloc(1, sizeof(*hdr));
- hdr->name = name;
+ hdr->name = strdup(name);
- hash_table_insert(table->ht, hdr, name);
+ hash_table_insert(table->ht, hdr, hdr->name);
hdr->next = table->hdr;
table->hdr = hdr;
}
check_symbol_table(table);
+ /* If the symbol already exists in this namespace at this scope, it cannot
+ * be added to the table.
+ */
+ for (sym = hdr->symbols
+ ; (sym != NULL) && (sym->name_space != name_space)
+ ; sym = sym->next_with_same_name) {
+ /* empty */
+ }
+
+ if (sym && (sym->depth == table->depth))
+ return -1;
+
sym = calloc(1, sizeof(*sym));
sym->next_with_same_name = hdr->symbols;
sym->next_with_same_scope = table->current_scope->symbols;
sym->hdr = hdr;
sym->name_space = name_space;
sym->data = declaration;
+ sym->depth = table->depth;
assert(sym->hdr == hdr);
@@ -354,6 +404,7 @@ _mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
for (hdr = table->hdr; hdr != NULL; hdr = next) {
next = hdr->next;
+ free(hdr->name);
free(hdr);
}
diff --git a/src/mesa/program/symbol_table.h b/src/mesa/program/symbol_table.h
index 0c054ef1396..1d570fc1a09 100644
--- a/src/mesa/program/symbol_table.h
+++ b/src/mesa/program/symbol_table.h
@@ -33,6 +33,9 @@ extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
int name_space, const char *name, void *declaration);
+extern int _mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+ int name_space, const char *name);
+
extern void *_mesa_symbol_table_find_symbol(
struct _mesa_symbol_table *symtab, int name_space, const char *name);
diff --git a/src/mesa/slang/descrip.mms b/src/mesa/slang/descrip.mms
deleted file mode 100644
index 674b786ac08..00000000000
--- a/src/mesa/slang/descrip.mms
+++ /dev/null
@@ -1,67 +0,0 @@
-# Makefile for core library for VMS
-# contributed by Jouk Jansen [email protected]
-# Last revision : 3 October 2007
-
-.first
- define gl [----.include.gl]
- define math [--.math]
- define swrast [--.swrast]
- define array_cache [--.array_cache]
- define main [--.main]
- define glapi [--.glapi]
- define shader [--.shader]
-
-.include [----]mms-config.
-
-##### MACROS #####
-
-VPATH = RCS
-
-INCDIR = [----.include],[--.main],[--.glapi],[-.slang],[-]
-LIBDIR = [----.lib]
-CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm
-
-SOURCES = \
- slang_compile.c
-
-OBJECTS = slang_builtin.obj,slang_codegen.obj,slang_compile.obj,\
- slang_compile_function.obj,slang_compile_operation.obj,\
- slang_compile_struct.obj,slang_compile_variable.obj,slang_emit.obj,\
- slang_ir.obj,slang_label.obj,slang_library_noise.obj,slang_link.obj,\
- slang_log.obj,slang_mem.obj,slang_preprocess.obj,slang_print.obj,\
- slang_simplify.obj,slang_storage.obj,slang_typeinfo.obj,\
- slang_utility.obj,slang_vartable.obj
-
-##### RULES #####
-
-VERSION=Mesa V3.4
-
-##### TARGETS #####
-# Make the library
-$(LIBDIR)$(GL_LIB) : $(OBJECTS)
- @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
-
-clean :
- purge
- delete *.obj;*
-
-slang_builtin.obj : slang_builtin.c
-slang_codegen.obj : slang_codegen.c
-slang_compile.obj : slang_compile.c
-slang_compile_function.obj : slang_compile_function.c
-slang_compile_operation.obj : slang_compile_operation.c
-slang_compile_struct.obj : slang_compile_struct.c
-slang_compile_variable.obj : slang_compile_variable.c
-slang_emit.obj : slang_emit.c
-slang_ir.obj : slang_ir.c
-slang_label.obj : slang_label.c
-slang_library_noise.obj : slang_library_noise.c
-slang_link.obj : slang_link.c
-slang_log.obj : slang_log.c
-slang_mem.obj : slang_mem.c
-slang_print.obj : slang_print.c
-slang_simplify.obj : slang_simplify.c
-slang_storage.obj : slang_storage.c
-slang_typeinfo.obj : slang_typeinfo.c
-slang_utility.obj : slang_utility.c
-slang_vartable.obj : slang_vartable.c
diff --git a/src/mesa/slang/library/.gitignore b/src/mesa/slang/library/.gitignore
deleted file mode 100644
index 02a89fc7df7..00000000000
--- a/src/mesa/slang/library/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*_gc.h
diff --git a/src/mesa/slang/library/Makefile b/src/mesa/slang/library/Makefile
deleted file mode 100644
index f546a039072..00000000000
--- a/src/mesa/slang/library/Makefile
+++ /dev/null
@@ -1,54 +0,0 @@
-# src/mesa/slang/library/Makefile
-
-TOP = ../../../..
-
-include $(TOP)/configs/current
-
-GLSL_CL = $(TOP)/src/glsl/apps/compile
-
-#
-# targets
-#
-
-.PHONY: default clean
-
-default: builtin
-
-clean:
- -rm -f *_gc.h
-
-builtin: builtin_110 builtin_120
-
-#
-# builtin library sources
-#
-
-builtin_110: slang_common_builtin_gc.h slang_core_gc.h slang_fragment_builtin_gc.h slang_vertex_builtin_gc.h slang_geometry_builtin_gc.h
-
-builtin_120: slang_120_core_gc.h slang_builtin_120_common_gc.h slang_builtin_120_fragment_gc.h
-
-
-slang_120_core_gc.h: slang_120_core.gc
- $(GLSL_CL) fragment slang_120_core.gc slang_120_core_gc.h
-
-slang_builtin_120_common_gc.h: slang_builtin_120_common.gc
- $(GLSL_CL) fragment slang_builtin_120_common.gc slang_builtin_120_common_gc.h
-
-slang_builtin_120_fragment_gc.h: slang_builtin_120_fragment.gc
- $(GLSL_CL) fragment slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h
-
-slang_common_builtin_gc.h: slang_common_builtin.gc
- $(GLSL_CL) fragment slang_common_builtin.gc slang_common_builtin_gc.h
-
-slang_core_gc.h: slang_core.gc
- $(GLSL_CL) fragment slang_core.gc slang_core_gc.h
-
-slang_fragment_builtin_gc.h: slang_fragment_builtin.gc
- $(GLSL_CL) fragment slang_fragment_builtin.gc slang_fragment_builtin_gc.h
-
-slang_vertex_builtin_gc.h: slang_vertex_builtin.gc
- $(GLSL_CL) vertex slang_vertex_builtin.gc slang_vertex_builtin_gc.h
-
-slang_geometry_builtin_gc.h: slang_geometry_builtin.gc
- $(GLSL_CL) geometry slang_geometry_builtin.gc slang_geometry_builtin_gc.h
-
diff --git a/src/mesa/slang/library/SConscript b/src/mesa/slang/library/SConscript
deleted file mode 100644
index 5112cefb3eb..00000000000
--- a/src/mesa/slang/library/SConscript
+++ /dev/null
@@ -1,62 +0,0 @@
-#######################################################################
-# SConscript for GLSL builtin library
-
-Import('*')
-
-env = env.Clone()
-
-# See also http://www.scons.org/wiki/UsingCodeGenerators
-
-def glsl_compile_emitter(target, source, env):
- env.Depends(target, glsl_compile)
- return (target, source)
-
-bld_frag = Builder(
- action = Action(glsl_compile[0].abspath + ' fragment $SOURCE $TARGET', '$CODEGENCODESTR'),
- emitter = glsl_compile_emitter,
- suffix = '.gc',
- src_suffix = '_gc.h')
-
-bld_vert = Builder(
- action = Action(glsl_compile[0].abspath + ' vertex $SOURCE $TARGET', '$CODEGENCODESTR'),
- emitter = glsl_compile_emitter,
- suffix = '.gc',
- src_suffix = '_gc.h')
-
-bld_geom = Builder(
- action = Action(glsl_compile[0].abspath + ' geometry $SOURCE $TARGET', '$CODEGENCODESTR'),
- emitter = glsl_compile_emitter,
- suffix = '.gc',
- src_suffix = '_gc.h')
-
-env['BUILDERS']['bld_frag'] = bld_frag
-env['BUILDERS']['bld_vert'] = bld_vert
-env['BUILDERS']['bld_geom'] = bld_geom
-
-# Generate GLSL builtin library binaries
-env.bld_frag(
- '#src/mesa/slang/library/slang_core_gc.h',
- '#src/mesa/slang/library/slang_core.gc')
-env.bld_frag(
- '#src/mesa/slang/library/slang_common_builtin_gc.h',
- '#src/mesa/slang/library/slang_common_builtin.gc')
-env.bld_frag(
- '#src/mesa/slang/library/slang_fragment_builtin_gc.h',
- '#src/mesa/slang/library/slang_fragment_builtin.gc')
-env.bld_vert(
- '#src/mesa/slang/library/slang_vertex_builtin_gc.h',
- '#src/mesa/slang/library/slang_vertex_builtin.gc')
-env.bld_geom(
- '#src/mesa/slang/library/slang_geometry_builtin_gc.h',
- '#src/mesa/slang/library/slang_geometry_builtin.gc')
-
-# Generate GLSL 1.20 builtin library binaries
-env.bld_frag(
- '#src/mesa/slang/library/slang_120_core_gc.h',
- '#src/mesa/slang/library/slang_120_core.gc')
-env.bld_frag(
- '#src/mesa/slang/library/slang_builtin_120_common_gc.h',
- '#src/mesa/slang/library/slang_builtin_120_common.gc')
-env.bld_frag(
- '#src/mesa/slang/library/slang_builtin_120_fragment_gc.h',
- '#src/mesa/slang/library/slang_builtin_120_fragment.gc')
diff --git a/src/mesa/slang/library/slang_120_core.gc b/src/mesa/slang/library/slang_120_core.gc
deleted file mode 100644
index 04c5ec2ec5c..00000000000
--- a/src/mesa/slang/library/slang_120_core.gc
+++ /dev/null
@@ -1,1978 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 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.
- */
-
-//
-// Constructors and operators introduced in GLSL 1.20 - mostly on new
-// (non-square) types of matrices.
-//
-// One important change in the language is that when a matrix is used
-// as an argument to a matrix constructor, it must be the only argument
-// for the constructor. The compiler takes care of it by itself and
-// here we only care to re-introduce constructors for old (square)
-// types of matrices.
-//
-
-//
-// From Shader Spec, ver. 1.20, rev. 6
-//
-
-//// mat2x3: 2 columns of vec3
-
-mat2x3 __constructor(const float f00, const float f10, const float f20,
- const float f01, const float f11, const float f21)
-{
- __retVal[0].x = f00;
- __retVal[0].y = f10;
- __retVal[0].z = f20;
- __retVal[1].x = f01;
- __retVal[1].y = f11;
- __retVal[1].z = f21;
-}
-
-mat2x3 __constructor(const float f)
-{
- __retVal = mat2x3( f, 0.0, 0.0,
- 0.0, f, 0.0);
-}
-
-mat2x3 __constructor(const int i)
-{
- const float f = float(i);
- __retVal = mat2x3(f);
-}
-
-mat2x3 __constructor(const bool b)
-{
- const float f = float(b);
- __retVal = mat2x3(f);
-}
-
-mat2x3 __constructor(const vec3 c0, const vec3 c1)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
-}
-
-
-
-//// mat2x4: 2 columns of vec4
-
-mat2x4 __constructor(const float f00, const float f10, const float f20, const float f30,
- const float f01, const float f11, const float f21, const float f31)
-{
- __retVal[0].x = f00;
- __retVal[0].y = f10;
- __retVal[0].z = f20;
- __retVal[0].w = f30;
- __retVal[1].x = f01;
- __retVal[1].y = f11;
- __retVal[1].z = f21;
- __retVal[1].w = f31;
-}
-
-mat2x4 __constructor(const float f)
-{
- __retVal = mat2x4( f, 0.0, 0.0, 0.0,
- 0.0, f, 0.0, 0.0);
-}
-
-mat2x4 __constructor(const int i)
-{
- const float f = float(i);
- __retVal = mat2x4(f);
-}
-
-mat2x4 __constructor(const bool b)
-{
- const float f = float(b);
- __retVal = mat2x4(f);
-}
-
-mat2x4 __constructor(const vec4 c0, const vec4 c1)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
-}
-
-
-
-//// mat3x2: 3 columns of vec2
-
-mat3x2 __constructor(const float f00, const float f10,
- const float f01, const float f11,
- const float f02, const float f12)
-{
- __retVal[0].x = f00;
- __retVal[0].y = f10;
- __retVal[1].x = f01;
- __retVal[1].y = f11;
- __retVal[2].x = f02;
- __retVal[2].y = f12;
-}
-
-mat3x2 __constructor(const float f)
-{
- __retVal = mat3x2( f, 0.0,
- 0.0, f,
- 0.0, 0.0);
-}
-
-mat3x2 __constructor(const int i)
-{
- const float f = float(i);
- __retVal = mat3x2(f);
-}
-
-mat3x2 __constructor(const bool b)
-{
- const float f = float(b);
- __retVal = mat3x2(f);
-}
-
-mat3x2 __constructor(const vec2 c0, const vec2 c1, const vec2 c2)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
- __retVal[2] = c2;
-}
-
-
-
-//// mat3x4: 3 columns of vec4
-
-mat3x4 __constructor(const float f00, const float f10, const float f20, const float f30,
- const float f01, const float f11, const float f21, const float f31,
- const float f02, const float f12, const float f22, const float f32)
-{
- __retVal[0].x = f00;
- __retVal[0].y = f10;
- __retVal[0].z = f20;
- __retVal[0].w = f30;
- __retVal[1].x = f01;
- __retVal[1].y = f11;
- __retVal[1].z = f21;
- __retVal[1].w = f31;
- __retVal[2].x = f02;
- __retVal[2].y = f12;
- __retVal[2].z = f22;
- __retVal[2].w = f32;
-}
-
-mat3x4 __constructor(const float f)
-{
- __retVal = mat3x4( f, 0.0, 0.0, 0.0,
- 0.0, f, 0.0, 0.0,
- 0.0, 0.0, f, 0.0);
-}
-
-mat3x4 __constructor(const int i)
-{
- const float f = float(i);
- __retVal = mat3x4(f);
-}
-
-mat3x4 __constructor(const bool b)
-{
- const float f = float(b);
- __retVal = mat3x4(f);
-}
-
-mat3x4 __constructor(const vec4 c0, const vec4 c1, const vec4 c2)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
- __retVal[2] = c2;
-}
-
-
-
-//// mat4x2: 4 columns of vec2
-
-mat4x2 __constructor(const float f00, const float f10,
- const float f01, const float f11,
- const float f02, const float f12,
- const float f03, const float f13)
-{
- __retVal[0].x = f00;
- __retVal[0].y = f10;
- __retVal[1].x = f01;
- __retVal[1].y = f11;
- __retVal[2].x = f02;
- __retVal[2].y = f12;
- __retVal[3].x = f03;
- __retVal[3].y = f13;
-}
-
-mat4x2 __constructor(const float f)
-{
- __retVal = mat4x2( f, 0.0,
- 0.0, 4,
- 0.0, 0.0,
- 0.0, 0.0);
-}
-
-mat4x2 __constructor(const int i)
-{
- const float f = float(i);
- __retVal = mat4x2(f);
-}
-
-mat4x2 __constructor(const bool b)
-{
- const float f = float(b);
- __retVal = mat4x2(f);
-}
-
-mat4x2 __constructor(const vec2 c0, const vec2 c1, const vec2 c2, const vec2 c3)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
- __retVal[2] = c2;
- __retVal[3] = c3;
-}
-
-
-
-//// mat4x3: 4 columns of vec3
-
-mat4x3 __constructor(const float f00, const float f10, const float f20,
- const float f01, const float f11, const float f21,
- const float f02, const float f12, const float f22,
- const float f03, const float f13, const float f23)
-{
- __retVal[0].x = f00;
- __retVal[0].y = f10;
- __retVal[0].z = f20;
- __retVal[1].x = f01;
- __retVal[1].y = f11;
- __retVal[1].z = f21;
- __retVal[2].x = f02;
- __retVal[2].y = f12;
- __retVal[2].z = f22;
- __retVal[3].x = f03;
- __retVal[3].y = f13;
- __retVal[3].z = f23;
-}
-
-mat4x3 __constructor(const float f)
-{
- __retVal = mat4x3( f, 0.0, 0.0,
- 0.0, f, 0.0,
- 0.0, 0.0, f,
- 0.0, 0.0, 0.0);
-}
-
-mat4x3 __constructor(const int i)
-{
- const float f = float(i);
- __retVal = mat4x3(f);
-}
-
-mat4x3 __constructor(const bool b)
-{
- const float f = float(b);
- __retVal = mat4x3(f);
-}
-
-mat4x3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2, const vec3 c3)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
- __retVal[2] = c2;
- __retVal[3] = c3;
-}
-
-
-
-//// misc assorted matrix constructors
-
-mat2 __constructor(const mat2 m)
-{
- __retVal = m;
-}
-
-mat2 __constructor(const mat3x2 m)
-{
- __retVal = mat2(m[0], m[1]);
-}
-
-mat2 __constructor(const mat4x2 m)
-{
- __retVal = mat2(m[0], m[1]);
-}
-
-mat2 __constructor(const mat2x3 m)
-{
- __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat2x4 m)
-{
- __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat3 m)
-{
- __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat3x4 m)
-{
- __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat4x3 m)
-{
- __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat4 m)
-{
- __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-
-
-mat2x3 __constructor(const mat2x3 m)
-{
- __retVal = m;
-}
-
-mat2x3 __constructor(const mat3 m)
-{
- __retVal = mat2x3(m[0], m[1]);
-}
-
-mat2x3 __constructor(const mat4x3 m)
-{
- __retVal = mat2x3(m[0], m[1]);
-}
-
-mat2x3 __constructor(const mat2x4 m)
-{
- __retVal = mat2x3(m[0].xyz, m[1].xyz);
-}
-
-mat2x3 __constructor(const mat3x4 m)
-{
- __retVal = mat2x3(m[0].xyz, m[1].xyz);
-}
-
-mat2x3 __constructor(const mat4 m)
-{
- __retVal = mat2x3(m[0].xyz, m[1].xyz);
-}
-
-mat2x3 __constructor(const mat2 m)
-{
- __retVal = mat2x3(m[0].x, m[0].y, 0.0,
- m[1].x, m[1].y, 0.0);
-}
-
-mat2x3 __constructor(const mat3x2 m)
-{
- __retVal = mat2x3(m[0].x, m[0].y, 0.0,
- m[1].x, m[1].y, 0.0);
-}
-
-mat2x3 __constructor(const mat4x2 m)
-{
- __retVal = mat2x3(m[0].x, m[0].y, 0.0,
- m[1].x, m[1].y, 0.0);
-}
-
-
-
-mat2x4 __constructor(const mat2x4 m)
-{
- __retVal = m;
-}
-
-mat2x4 __constructor(const mat3x4 m)
-{
- __retVal = mat2x4(m[0], m[1]);
-}
-
-mat2x4 __constructor(const mat4 m)
-{
- __retVal = mat2x4(m[0], m[1]);
-}
-
-mat2x4 __constructor(const mat2x3 m)
-{
- __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
- m[1].x, m[1].y, m[1].z, 0.0);
-}
-
-mat2x4 __constructor(const mat3 m)
-{
- __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
- m[1].x, m[1].y, m[1].z, 0.0);
-}
-
-mat2x4 __constructor(const mat4x3 m)
-{
- __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
- m[1].x, m[1].y, m[1].z, 0.0);
-}
-
-mat2x4 __constructor(const mat2 m)
-{
- __retVal = mat2x4(m[0].x, m[1].y, 0.0, 0.0,
- m[1].x, m[1].y, 0.0, 0.0);
-}
-
-mat2x4 __constructor(const mat3x2 m)
-{
- __retVal = mat2x4(m[0].x, m[0].y, 0.0, 0.0,
- m[1].x, m[1].y, 0.0, 0.0);
-}
-
-mat2x4 __constructor(const mat4x2 m)
-{
- __retVal = mat2x4(m[0].x, m[0].y, 0.0, 0.0,
- m[1].x, m[1].y, 0.0, 0.0);
-}
-
-
-
-mat3x2 __constructor(const mat3x2 m)
-{
- __retVal = m;
-}
-
-mat3x2 __constructor(const mat4x2 m)
-{
- __retVal = mat3x2(m[0], m[1], m[2]);
-}
-
-mat3x2 __constructor(const mat3 m)
-{
- __retVal = mat3x2(m[0], m[1], m[2]);
-}
-
-mat3x2 __constructor(const mat3x4 m)
-{
- __retVal = mat3x2(m[0].x, m[0].y,
- m[1].x, m[1].y,
- m[2].x, m[2].y);
-}
-
-mat3x2 __constructor(const mat4x3 m)
-{
- __retVal = mat3x2(m[0].x, m[0].y,
- m[1].x, m[1].y,
- m[2].x, m[2].y);
-}
-
-mat3x2 __constructor(const mat4 m)
-{
- __retVal = mat3x2(m[0].x, m[0].y,
- m[1].x, m[1].y,
- 0.0, 0.0);
-}
-
-mat3x2 __constructor(const mat2 m)
-{
- __retVal = mat3x2(m[0], m[1], vec2(0.0));
-}
-
-mat3x2 __constructor(const mat2x3 m)
-{
- __retVal = mat3x2(m[0].x, m[0].y,
- m[1].x, m[1].y,
- 0.0, 0.0);
-}
-
-mat3x2 __constructor(const mat2x4 m)
-{
- __retVal = mat3x2(m[0].x, m[0].y,
- m[1].x, m[1].y,
- 0.0, 0.0);
-}
-
-
-
-
-mat3 __constructor(const mat3 m)
-{
- __retVal = m;
-}
-
-mat3 __constructor(const mat4x3 m)
-{
- __retVal = mat3 (
- m[0],
- m[1],
- m[2]
- );
-}
-
-mat3 __constructor(const mat3x4 m)
-{
- __retVal = mat3 (
- m[0].xyz,
- m[1].xyz,
- m[2].xyz
- );
-}
-
-mat3 __constructor(const mat4 m)
-{
- __retVal = mat3 (
- m[0].xyz,
- m[1].xyz,
- m[2].xyz
- );
-}
-
-mat3 __constructor(const mat2x3 m)
-{
- __retVal = mat3 (
- m[0],
- m[1],
- 0., 0., 1.
- );
-}
-
-mat3 __constructor(const mat2x4 m)
-{
- __retVal = mat3 (
- m[0].xyz,
- m[1].xyz,
- 0., 0., 1.
- );
-}
-
-mat3 __constructor(const mat3x2 m)
-{
- __retVal = mat3 (
- m[0], 0.,
- m[1], 0.,
- m[2], 1.
- );
-}
-
-mat3 __constructor(const mat4x2 m)
-{
- __retVal = mat3 (
- m[0], 0.,
- m[1], 0.,
- m[2], 1.
- );
-}
-
-mat3 __constructor(const mat2 m)
-{
- __retVal = mat3 (
- m[0], 0.,
- m[1], 0.,
- 0., 0., 1.
- );
-}
-
-
-mat3x4 __constructor(const mat3x4 m)
-{
- __retVal = m;
-}
-
-mat3x4 __constructor(const mat4 m)
-{
- __retVal = mat3x4 (
- m[0],
- m[1],
- m[2]
- );
-}
-
-mat3x4 __constructor(const mat3 m)
-{
- __retVal = mat3x4 (
- m[0], 0.,
- m[1], 0.,
- m[2], 0.
- );
-}
-
-mat3x4 __constructor(const mat4x3 m)
-{
- __retVal = mat3x4 (
- m[0], 0.,
- m[1], 0.,
- m[2], 0.
- );
-}
-
-mat3x4 __constructor(const mat2x4 m)
-{
- __retVal = mat3x4 (
- m[0],
- m[1],
- 0., 0., 1., 0.
- );
-}
-
-mat3x4 __constructor(const mat2x3 m)
-{
- __retVal = mat3x4 (
- m[0], 0.,
- m[1], 0.,
- 0., 0., 1., 0.
- );
-}
-
-mat3x4 __constructor(const mat3x2 m)
-{
- __retVal = mat3x4 (
- m[0], 0., 0.,
- m[1], 0., 0.,
- m[2], 1., 0.
- );
-}
-
-mat3x4 __constructor(const mat4x2 m)
-{
- __retVal = mat3x4 (
- m[0], 0., 0.,
- m[1], 0., 0.,
- m[2], 1., 0.
- );
-}
-
-mat3x4 __constructor(const mat2 m)
-{
- __retVal = mat3x4 (
- m[0], 0., 0.,
- m[1], 0., 0.,
- 0., 0., 1., 0.
- );
-}
-
-
-mat4x2 __constructor(const mat4x2 m)
-{
- __retVal = m;
-}
-
-mat4x2 __constructor(const mat4x3 m)
-{
- __retVal = mat4x2 (
- m[0].xy,
- m[1].xy,
- m[2].xy,
- m[3].xy
- );
-}
-
-mat4x2 __constructor(const mat4 m)
-{
- __retVal = mat4x2 (
- m[0].xy,
- m[1].xy,
- m[2].xy,
- m[3].xy
- );
-}
-
-mat4x2 __constructor(const mat3x2 m)
-{
- __retVal = mat4x2 (
- m[0],
- m[1],
- 0., 0.
- );
-}
-
-mat4x2 __constructor(const mat3 m)
-{
- __retVal = mat4x2 (
- m[0].xy,
- m[1].xy,
- m[2].xy,
- 0., 0.
- );
-}
-
-mat4x2 __constructor(const mat3x4 m)
-{
- __retVal = mat4x2 (
- m[0].xy,
- m[1].xy,
- m[2].xy,
- 0., 0.
- );
-}
-
-mat4x2 __constructor(const mat2 m)
-{
- __retVal = mat4x2 (
- m[0],
- m[1],
- 0., 0.,
- 0., 0.
- );
-}
-
-mat4x2 __constructor(const mat2x3 m)
-{
- __retVal = mat4x2 (
- m[0].xy,
- m[1].xy,
- 0., 0.,
- 0., 0.
- );
-}
-
-mat4x2 __constructor(const mat2x4 m)
-{
- __retVal = mat4x2 (
- m[0].xy,
- m[1].xy,
- 0., 0.,
- 0., 0.
- );
-}
-
-
-mat4x3 __constructor(const mat4x3 m)
-{
- __retVal = m;
-}
-
-mat4x3 __constructor(const mat4 m)
-{
- __retVal = mat4x3 (
- m[0].xyz,
- m[1].xyz,
- m[2].xyz,
- m[3].xyz
- );
-}
-
-mat4x3 __constructor(const mat3 m)
-{
- __retVal = mat4x3 (
- m[0],
- m[1],
- m[2],
- 0., 0., 0.
- );
-}
-
-mat4x3 __constructor(const mat3x4 m)
-{
- __retVal = mat4x3 (
- m[0].xyz,
- m[1].xyz,
- m[2].xyz,
- 0., 0., 0.
- );
-}
-
-mat4x3 __constructor(const mat4x2 m)
-{
- __retVal = mat4x3 (
- m[0], 0.,
- m[1], 0.,
- m[2], 1.,
- m[3], 0.
- );
-}
-
-mat4x3 __constructor(const mat2x3 m)
-{
- __retVal = mat4x3 (
- m[0],
- m[1],
- 0., 0., 1.,
- 0., 0., 0.
- );
-}
-
-mat4x3 __constructor(const mat3x2 m)
-{
- __retVal = mat4x3 (
- m[0], 0.,
- m[1], 0.,
- m[2], 1.,
- 0., 0., 0.
- );
-}
-
-mat4x3 __constructor(const mat2x4 m)
-{
- __retVal = mat4x3 (
- m[0].xyz,
- m[1].xyz,
- 0., 0., 1.,
- 0., 0., 0.
- );
-}
-
-mat4x3 __constructor(const mat2 m)
-{
- __retVal = mat4x3 (
- m[0], 0.,
- m[1], 0.,
- 0., 0., 1.,
- 0., 0., 0.
- );
-}
-
-
-mat4 __constructor(const mat4 m)
-{
- __retVal = m;
-}
-
-mat4 __constructor(const mat3x4 m)
-{
- __retVal = mat4 (
- m[0],
- m[1],
- m[2],
- 0., 0., 0., 1.
- );
-}
-
-mat4 __constructor(const mat4x3 m)
-{
- __retVal = mat4 (
- m[0], 0.,
- m[1], 0.,
- m[2], 0.,
- m[3], 1.
- );
-}
-
-mat4 __constructor(const mat2x4 m)
-{
- __retVal = mat4 (
- m[0],
- m[1],
- 0., 0., 1., 0.,
- 0., 0., 0., 1.
- );
-}
-
-mat4 __constructor(const mat4x2 m)
-{
- __retVal = mat4 (
- m[0], 0., 0.,
- m[1], 0., 0.,
- m[2], 1., 0.,
- m[3], 0., 1.
- );
-}
-
-mat4 __constructor(const mat3 m)
-{
- __retVal = mat4 (
- m[0], 0.,
- m[1], 0.,
- m[2], 0.,
- 0., 0., 0., 1.
- );
-}
-
-mat4 __constructor(const mat2x3 m)
-{
- __retVal = mat4 (
- m[0], 0.,
- m[1], 0.,
- 0., 0., 1., 0.,
- 0., 0., 0., 1.
- );
-}
-
-mat4 __constructor(const mat3x2 m)
-{
- __retVal = mat4 (
- m[0], 0., 0.,
- m[1], 0., 0.,
- m[2], 1., 0.,
- 0., 0., 0., 1.
- );
-}
-
-mat4 __constructor(const mat2 m)
-{
- __retVal = mat4 (
- m[0], 0., 0.,
- m[1], 0., 0.,
- 0., 0., 1., 0.,
- 0., 0., 0., 1.
- );
-}
-
-
-void __operator += (inout mat2x3 m, const mat2x3 n) {
- m[0] += n[0];
- m[1] += n[1];
-}
-
-void __operator += (inout mat2x4 m, const mat2x4 n) {
- m[0] += n[0];
- m[1] += n[1];
-}
-
-void __operator += (inout mat3x2 m, const mat3x2 n) {
- m[0] += n[0];
- m[1] += n[1];
- m[2] += n[2];
-}
-
-void __operator += (inout mat3x4 m, const mat3x4 n) {
- m[0] += n[0];
- m[1] += n[1];
- m[2] += n[2];
-}
-
-void __operator += (inout mat4x2 m, const mat4x2 n) {
- m[0] += n[0];
- m[1] += n[1];
- m[2] += n[2];
- m[3] += n[3];
-}
-
-void __operator += (inout mat4x3 m, const mat4x3 n) {
- m[0] += n[0];
- m[1] += n[1];
- m[2] += n[2];
- m[3] += n[3];
-}
-
-
-void __operator -= (inout mat2x3 m, const mat2x3 n) {
- m[0] -= n[0];
- m[1] -= n[1];
-}
-
-void __operator -= (inout mat2x4 m, const mat2x4 n) {
- m[0] -= n[0];
- m[1] -= n[1];
-}
-
-void __operator -= (inout mat3x2 m, const mat3x2 n) {
- m[0] -= n[0];
- m[1] -= n[1];
- m[2] -= n[2];
-}
-
-void __operator -= (inout mat3x4 m, const mat3x4 n) {
- m[0] -= n[0];
- m[1] -= n[1];
- m[2] -= n[2];
-}
-
-void __operator -= (inout mat4x2 m, const mat4x2 n) {
- m[0] -= n[0];
- m[1] -= n[1];
- m[2] -= n[2];
- m[3] -= n[3];
-}
-
-void __operator -= (inout mat4x3 m, const mat4x3 n) {
- m[0] -= n[0];
- m[1] -= n[1];
- m[2] -= n[2];
- m[3] -= n[3];
-}
-
-
-void __operator /= (inout mat2x3 m, const mat2x3 n) {
- m[0] /= n[0];
- m[1] /= n[1];
-}
-
-void __operator /= (inout mat2x4 m, const mat2x4 n) {
- m[0] /= n[0];
- m[1] /= n[1];
-}
-
-void __operator /= (inout mat3x2 m, const mat3x2 n) {
- m[0] /= n[0];
- m[1] /= n[1];
- m[2] /= n[2];
-}
-
-void __operator /= (inout mat3x4 m, const mat3x4 n) {
- m[0] /= n[0];
- m[1] /= n[1];
- m[2] /= n[2];
-}
-
-void __operator /= (inout mat4x2 m, const mat4x2 n) {
- m[0] /= n[0];
- m[1] /= n[1];
- m[2] /= n[2];
- m[3] /= n[3];
-}
-
-void __operator /= (inout mat4x3 m, const mat4x3 n) {
- m[0] /= n[0];
- m[1] /= n[1];
- m[2] /= n[2];
- m[3] /= n[3];
-}
-
-
-vec3 __operator * (const mat2x3 m, const vec2 v)
-{
- __retVal.x = v.x * m[0].x + v.y * m[1].x;
- __retVal.y = v.x * m[0].y + v.y * m[1].y;
- __retVal.z = v.x * m[0].z + v.y * m[1].z;
-}
-
-vec4 __operator * (const mat2x4 m, const vec2 v)
-{
- __retVal.x = v.x * m[0].x + v.y * m[1].x;
- __retVal.y = v.x * m[0].y + v.y * m[1].y;
- __retVal.z = v.x * m[0].z + v.y * m[1].z;
- __retVal.w = v.x * m[0].w + v.y * m[1].w;
-}
-
-vec2 __operator * (const mat3x2 m, const vec3 v)
-{
- __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x;
- __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y;
-}
-
-vec4 __operator * (const mat3x4 m, const vec3 v)
-{
- __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x;
- __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y;
- __retVal.z = v.x * m[0].z + v.y * m[1].z + v.z * m[2].z;
- __retVal.w = v.x * m[0].w + v.y * m[1].w + v.z * m[2].w;
-}
-
-vec2 __operator * (const mat4x2 m, const vec4 v)
-{
- __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x;
- __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y;
-}
-
-vec3 __operator * (const mat4x3 m, const vec4 v)
-{
- __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x;
- __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y;
- __retVal.z = v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z;
-}
-
-
-mat3x2 __operator * (const mat2 m, const mat3x2 n)
-{
- //return mat3x2 (m * n[0], m * n[1], m * n[2]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
-}
-
-mat4x2 __operator * (const mat2 m, const mat4x2 n)
-{
- //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
- __retVal[3] = m * n[3];
-}
-
-
-mat2x3 __operator * (const mat2x3 m, const mat2 n)
-{
- //return mat2x3 (m * n[0], m * n[1]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
-}
-
-mat3 __operator * (const mat2x3 m, const mat3x2 n)
-{
- //return mat3 (m * n[0], m * n[1], m * n[2]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
-}
-
-mat4x3 __operator * (const mat2x3 m, const mat4x2 n)
-{
- //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
- __retVal[3] = m * n[3];
-}
-
-
-mat2x4 __operator * (const mat2x4 m, const mat2 n)
-{
- //return mat2x4 (m * n[0], m * n[1]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
-}
-
-mat3x4 __operator * (const mat2x4 m, const mat3x2 n)
-{
- //return mat3x4 (m * n[0], m * n[1], m * n[2]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
-}
-
-mat4 __operator * (const mat2x4 m, const mat4x2 n)
-{
- //return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
- __retVal[3] = m * n[3];
-}
-
-
-mat2 __operator * (const mat3x2 m, const mat2x3 n)
-{
- //return mat2 (m * n[0], m * n[1]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
-}
-
-mat3x2 __operator * (const mat3x2 m, const mat3 n)
-{
- //return mat3x2 (m * n[0], m * n[1], m * n[2]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
-}
-
-mat4x2 __operator * (const mat3x2 m, const mat4x3 n)
-{
- //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
- __retVal[3] = m * n[3];
-}
-
-
-mat2x3 __operator * (const mat3 m, const mat2x3 n)
-{
- //return mat2x3 (m * n[0], m * n[1]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
-}
-
-mat4x3 __operator * (const mat3 m, const mat4x3 n)
-{
- //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
- __retVal[3] = m * n[3];
-}
-
-
-mat2x4 __operator * (const mat3x4 m, const mat2x3 n)
-{
- //return mat2x4 (m * n[0], m * n[1]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
-}
-
-mat3x4 __operator * (const mat3x4 m, const mat3 n)
-{
- //return mat3x4 (m * n[0], m * n[1], m * n[2]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
-}
-
-mat4 __operator * (const mat3x4 m, const mat4x3 n)
-{
- //return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
- __retVal[3] = m * n[3];
-}
-
-
-mat2 __operator * (const mat4x2 m, const mat2x4 n)
-{
- //return = mat2 (m * n[0], m * n[1]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
-}
-
-mat3x2 __operator * (const mat4x2 m, const mat3x4 n)
-{
- //return mat3x2 (m * n[0], m * n[1], m * n[2]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
-}
-
-mat4x2 __operator * (const mat4x2 m, const mat4 n)
-{
- //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
- __retVal[3] = m * n[3];
-}
-
-
-mat2x3 __operator * (const mat4x3 m, const mat2x4 n)
-{
- //return mat2x3 (m * n[0], m * n[1]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
-}
-
-mat3 __operator * (const mat4x3 m, const mat3x4 n)
-{
- //return mat3 (m * n[0], m * n[1], m * n[2]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
-}
-
-mat4x3 __operator * (const mat4x3 m, const mat4 n)
-{
- //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
- __retVal[3] = m * n[3];
-}
-
-
-mat2x4 __operator * (const mat4 m, const mat2x4 n)
-{
- //return mat2x4 (m * n[0], m * n[1]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
-}
-
-mat3x4 __operator * (const mat4 m, const mat3x4 n)
-{
- //return mat3x4 (m * n[0], m * n[1], m * n[2]);
- __retVal[0] = m * n[0];
- __retVal[1] = m * n[1];
- __retVal[2] = m * n[2];
-}
-
-
-void __operator *= (inout mat2x3 m, const mat2 n) {
- m = m * n;
-}
-
-void __operator *= (inout mat2x4 m, const mat2 n) {
- m = m * n;
-}
-
-void __operator *= (inout mat3x2 m, const mat3 n) {
- m = m * n;
-}
-
-void __operator *= (inout mat3x4 m, const mat3 n) {
- m = m * n;
-}
-
-void __operator *= (inout mat4x2 m, const mat4 n) {
- m = m * n;
-}
-
-void __operator *= (inout mat4x3 m, const mat4 n) {
- m = m * n;
-}
-
-
-vec3 __operator * (const vec2 v, const mat3x2 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
- __retVal.z = dot(v, m[2]);
-}
-
-vec4 __operator * (const vec2 v, const mat4x2 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
- __retVal.z = dot(v, m[2]);
- __retVal.w = dot(v, m[3]);
-}
-
-vec2 __operator * (const vec3 v, const mat2x3 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
-}
-
-vec4 __operator * (const vec3 v, const mat4x3 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
- __retVal.z = dot(v, m[2]);
- __retVal.w = dot(v, m[3]);
-}
-
-vec2 __operator * (const vec4 v, const mat2x4 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
-}
-
-vec3 __operator * (const vec4 v, const mat3x4 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
- __retVal.z = dot(v, m[2]);
-}
-
-
-void __operator += (inout mat2x3 m, const float a) {
- m[0] += a;
- m[1] += a;
-}
-
-void __operator += (inout mat2x4 m, const float a) {
- m[0] += a;
- m[1] += a;
-}
-
-void __operator += (inout mat3x2 m, const float a) {
- m[0] += a;
- m[1] += a;
- m[2] += a;
-}
-
-void __operator += (inout mat3x4 m, const float a) {
- m[0] += a;
- m[1] += a;
- m[2] += a;
-}
-
-void __operator += (inout mat4x2 m, const float a) {
- m[0] += a;
- m[1] += a;
- m[2] += a;
- m[3] += a;
-}
-
-void __operator += (inout mat4x3 m, const float a) {
- m[0] += a;
- m[1] += a;
- m[2] += a;
- m[3] += a;
-}
-
-
-void __operator -= (inout mat2x3 m, const float a) {
- m[0] -= a;
- m[1] -= a;
-}
-
-void __operator -= (inout mat2x4 m, const float a) {
- m[0] -= a;
- m[1] -= a;
-}
-
-void __operator -= (inout mat3x2 m, const float a) {
- m[0] -= a;
- m[1] -= a;
- m[2] -= a;
-}
-
-void __operator -= (inout mat3x4 m, const float a) {
- m[0] -= a;
- m[1] -= a;
- m[2] -= a;
-}
-
-void __operator -= (inout mat4x2 m, const float a) {
- m[0] -= a;
- m[1] -= a;
- m[2] -= a;
- m[3] -= a;
-}
-
-void __operator -= (inout mat4x3 m, const float a) {
- m[0] -= a;
- m[1] -= a;
- m[2] -= a;
- m[3] -= a;
-}
-
-
-void __operator *= (inout mat2x3 m, const float a) {
- m[0] *= a;
- m[1] *= a;
-}
-
-void __operator *= (inout mat2x4 m, const float a) {
- m[0] *= a;
- m[1] *= a;
-}
-
-void __operator *= (inout mat3x2 m, const float a) {
- m[0] *= a;
- m[1] *= a;
- m[2] *= a;
-}
-
-void __operator *= (inout mat3x4 m, const float a) {
- m[0] *= a;
- m[1] *= a;
- m[2] *= a;
-}
-
-void __operator *= (inout mat4x2 m, const float a) {
- m[0] *= a;
- m[1] *= a;
- m[2] *= a;
- m[3] *= a;
-}
-
-void __operator *= (inout mat4x3 m, const float a) {
- m[0] *= a;
- m[1] *= a;
- m[2] *= a;
- m[3] *= a;
-}
-
-
-void __operator /= (inout mat2x3 m, const float a) {
- m[0] /= a;
- m[1] /= a;
-}
-
-void __operator /= (inout mat2x4 m, const float a) {
- m[0] /= a;
- m[1] /= a;
-}
-
-void __operator /= (inout mat3x2 m, const float a) {
- m[0] /= a;
- m[1] /= a;
- m[2] /= a;
-}
-
-void __operator /= (inout mat3x4 m, const float a) {
- m[0] /= a;
- m[1] /= a;
- m[2] /= a;
-}
-
-void __operator /= (inout mat4x2 m, const float a) {
- m[0] /= a;
- m[1] /= a;
- m[2] /= a;
- m[3] /= a;
-}
-
-void __operator /= (inout mat4x3 m, const float a) {
- m[0] /= a;
- m[1] /= a;
- m[2] /= a;
- m[3] /= a;
-}
-
-
-mat2x3 __operator + (const mat2x3 m, const mat2x3 n) {
- return mat2x3 (m[0] + n[0], m[1] + n[1]);
-}
-
-mat2x4 __operator + (const mat2x4 m, const mat2x4 n) {
- return mat2x4 (m[0] + n[0], m[1] + n[1]);
-}
-
-mat3x2 __operator + (const mat3x2 m, const mat3x2 n) {
- return mat3x2 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
-}
-
-mat3x4 __operator + (const mat3x4 m, const mat3x4 n) {
- return mat3x4 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
-}
-
-mat4x2 __operator + (const mat4x2 m, const mat4x2 n) {
- return mat4x2 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);
-}
-
-mat4x3 __operator + (const mat4x3 m, const mat4x3 n) {
- return mat4x3 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);
-}
-
-
-mat2x3 __operator - (const mat2x3 m, const mat2x3 n) {
- return mat2x3 (m[0] - n[0], m[1] - n[1]);
-}
-
-mat2x4 __operator - (const mat2x4 m, const mat2x4 n) {
- return mat2x4 (m[0] - n[0], m[1] - n[1]);
-}
-
-mat3x2 __operator - (const mat3x2 m, const mat3x2 n) {
- return mat3x2 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
-}
-
-mat3x4 __operator - (const mat3x4 m, const mat3x4 n) {
- return mat3x4 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
-}
-
-mat4x2 __operator - (const mat4x2 m, const mat4x2 n) {
- return mat4x2 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);
-}
-
-mat4x3 __operator - (const mat4x3 m, const mat4x3 n) {
- return mat4x3 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);
-}
-
-
-mat2x3 __operator / (const mat2x3 m, const mat2x3 n) {
- return mat2x3 (m[0] / n[0], m[1] / n[1]);
-}
-
-mat2x4 __operator / (const mat2x4 m, const mat2x4 n) {
- return mat2x4 (m[0] / n[0], m[1] / n[1]);
-}
-
-mat3x2 __operator / (const mat3x2 m, const mat3x2 n) {
- return mat3x2 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
-}
-
-mat3x4 __operator / (const mat3x4 m, const mat3x4 n) {
- return mat3x4 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
-}
-
-mat4x2 __operator / (const mat4x2 m, const mat4x2 n) {
- return mat4x2 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);
-}
-
-mat4x3 __operator / (const mat4x3 m, const mat4x3 n) {
- return mat4x3 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);
-}
-
-
-mat2x3 __operator + (const float a, const mat2x3 n) {
- return mat2x3 (a + n[0], a + n[1]);
-}
-
-mat2x3 __operator + (const mat2x3 m, const float b) {
- return mat2x3 (m[0] + b, m[1] + b);
-}
-
-mat2x4 __operator + (const float a, const mat2x4 n) {
- return mat2x4 (a + n[0], a + n[1]);
-}
-
-mat2x4 __operator + (const mat2x4 m, const float b) {
- return mat2x4 (m[0] + b, m[1] + b);
-}
-
-mat3x2 __operator + (const float a, const mat3x2 n) {
- return mat3x2 (a + n[0], a + n[1], a + n[2]);
-}
-
-mat3x2 __operator + (const mat3x2 m, const float b) {
- return mat3x2 (m[0] + b, m[1] + b, m[2] + b);
-}
-
-mat3x4 __operator + (const float a, const mat3x4 n) {
- return mat3x4 (a + n[0], a + n[1], a + n[2]);
-}
-
-mat3x4 __operator + (const mat3x4 m, const float b) {
- return mat3x4 (m[0] + b, m[1] + b, m[2] + b);
-}
-
-mat4x2 __operator + (const mat4x2 m, const float b) {
- return mat4x2 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
-}
-
-mat4x2 __operator + (const float a, const mat4x2 n) {
- return mat4x2 (a + n[0], a + n[1], a + n[2], a + n[3]);
-}
-
-mat4x3 __operator + (const mat4x3 m, const float b) {
- return mat4x3 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
-}
-
-mat4x3 __operator + (const float a, const mat4x3 n) {
- return mat4x3 (a + n[0], a + n[1], a + n[2], a + n[3]);
-}
-
-
-mat2x3 __operator - (const float a, const mat2x3 n) {
- return mat2x3 (a - n[0], a - n[1]);
-}
-
-mat2x3 __operator - (const mat2x3 m, const float b) {
- return mat2x3 (m[0] - b, m[1] - b);
-}
-
-mat2x4 __operator - (const float a, const mat2x4 n) {
- return mat2x4 (a - n[0], a - n[1]);
-}
-
-mat2x4 __operator - (const mat2x4 m, const float b) {
- return mat2x4 (m[0] - b, m[1] - b);
-}
-
-mat3x2 __operator - (const float a, const mat3x2 n) {
- return mat3x2 (a - n[0], a - n[1], a - n[2]);
-}
-
-mat3x2 __operator - (const mat3x2 m, const float b) {
- return mat3x2 (m[0] - b, m[1] - b, m[2] - b);
-}
-
-mat3x4 __operator - (const float a, const mat3x4 n) {
- return mat3x4 (a - n[0], a - n[1], a - n[2]);
-}
-
-mat3x4 __operator - (const mat3x4 m, const float b) {
- return mat3x4 (m[0] - b, m[1] - b, m[2] - b);
-}
-
-mat4x2 __operator - (const mat4x2 m, const float b) {
- return mat4x2 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
-}
-
-mat4x2 __operator - (const float a, const mat4x2 n) {
- return mat4x2 (a - n[0], a - n[1], a - n[2], a - n[3]);
-}
-
-mat4x3 __operator - (const mat4x3 m, const float b) {
- return mat4x3 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
-}
-
-mat4x3 __operator - (const float a, const mat4x3 n) {
- return mat4x3 (a - n[0], a - n[1], a - n[2], a - n[3]);
-}
-
-
-mat2x3 __operator * (const float a, const mat2x3 n)
-{
- //return mat2x3 (a * n[0], a * n[1]);
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
-}
-
-mat2x3 __operator * (const mat2x3 m, const float b)
-{
- //return mat2x3 (m[0] * b, m[1] * b);
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
-}
-
-mat2x4 __operator * (const float a, const mat2x4 n)
-{
- //return mat2x4 (a * n[0], a * n[1]);
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
-}
-
-mat2x4 __operator * (const mat2x4 m, const float b)
-{
- //return mat2x4 (m[0] * b, m[1] * b);
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
-}
-
-mat3x2 __operator * (const float a, const mat3x2 n)
-{
- //return mat3x2 (a * n[0], a * n[1], a * n[2]);
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
- __retVal[2] = a * n[2];
-}
-
-mat3x2 __operator * (const mat3x2 m, const float b)
-{
- //return mat3x2 (m[0] * b, m[1] * b, m[2] * b);
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
- __retVal[2] = m[2] * b;
-}
-
-mat3x4 __operator * (const float a, const mat3x4 n)
-{
- //return mat3x4 (a * n[0], a * n[1], a * n[2]);
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
- __retVal[2] = a * n[2];
-}
-
-mat3x4 __operator * (const mat3x4 m, const float b)
-{
- //return mat3x4 (m[0] * b, m[1] * b, m[2] * b);
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
- __retVal[2] = m[2] * b;
-}
-
-mat4x2 __operator * (const mat4x2 m, const float b)
-{
- //return mat4x2 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
- __retVal[2] = m[2] * b;
- __retVal[3] = m[3] * b;
-}
-
-mat4x2 __operator * (const float a, const mat4x2 n)
-{
- //return mat4x2 (a * n[0], a * n[1], a * n[2], a * n[3]);
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
- __retVal[2] = a * n[2];
- __retVal[3] = a * n[3];
-}
-
-mat4x3 __operator * (const mat4x3 m, const float b)
-{
- //return mat4x3 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
- __retVal[2] = m[2] * b;
- __retVal[3] = m[3] * b;
-}
-
-mat4x3 __operator * (const float a, const mat4x3 n)
-{
- //return mat4x3 (a * n[0], a * n[1], a * n[2], a * n[3]);
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
- __retVal[2] = a * n[2];
- __retVal[3] = a * n[3];
-}
-
-
-mat2x3 __operator / (const float a, const mat2x3 n)
-{
- //return mat2x3 (a / n[0], a / n[1]);
- const float inv = 1.0 / a;
- __retVal[0] = inv * n[0];
- __retVal[1] = inv * n[1];
-}
-
-mat2x3 __operator / (const mat2x3 m, const float b)
-{
- //return mat2x3 (m[0] / b, m[1] / b);
- const float inv = 1.0 / b;
- __retVal[0] = m[0] * inv;
- __retVal[1] = m[1] * inv;
-}
-
-mat2x4 __operator / (const float a, const mat2x4 n)
-{
- //return mat2x4 (a / n[0], a / n[1]);
- const float inv = 1.0 / a;
- __retVal[0] = inv * n[0];
- __retVal[1] = inv * n[1];
-}
-
-mat2x4 __operator / (const mat2x4 m, const float b)
-{
- //return mat2x4 (m[0] / b, m[1] / b);
- const float inv = 1.0 / b;
- __retVal[0] = m[0] * inv;
- __retVal[1] = m[1] * inv;
-}
-
-mat3x2 __operator / (const float a, const mat3x2 n)
-{
- //return mat3x2 (a / n[0], a / n[1], a / n[2]);
- const float inv = 1.0 / a;
- __retVal[0] = inv * n[0];
- __retVal[1] = inv * n[1];
- __retVal[2] = inv * n[2];
-}
-
-mat3x2 __operator / (const mat3x2 m, const float b)
-{
- //return mat3x2 (m[0] / b, m[1] / b, m[2] / b);
- const float inv = 1.0 / b;
- __retVal[0] = m[0] * inv;
- __retVal[1] = m[1] * inv;
- __retVal[2] = m[2] * inv;
-}
-
-mat3x4 __operator / (const float a, const mat3x4 n)
-{
- //return mat3x4 (a / n[0], a / n[1], a / n[2]);
- const float inv = 1.0 / a;
- __retVal[0] = inv * n[0];
- __retVal[1] = inv * n[1];
- __retVal[2] = inv * n[2];
-}
-
-mat3x4 __operator / (const mat3x4 m, const float b)
-{
- //return mat3x4 (m[0] / b, m[1] / b, m[2] / b);
- const float inv = 1.0 / b;
- __retVal[0] = m[0] * inv;
- __retVal[1] = m[1] * inv;
- __retVal[2] = m[2] * inv;
-}
-
-mat4x2 __operator / (const mat4x2 m, const float b)
-{
- //return mat4x2 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
- const float inv = 1.0 / b;
- __retVal[0] = m[0] * inv;
- __retVal[1] = m[1] * inv;
- __retVal[2] = m[2] * inv;
- __retVal[3] = m[3] * inv;
-}
-
-mat4x2 __operator / (const float a, const mat4x2 n)
-{
- //return mat4x2 (a / n[0], a / n[1], a / n[2], a / n[3]);
- const float inv = 1.0 / a;
- __retVal[0] = inv * n[0];
- __retVal[1] = inv * n[1];
- __retVal[2] = inv * n[2];
- __retVal[3] = inv * n[3];
-}
-
-mat4x3 __operator / (const mat4x3 m, const float b)
-{
- //return mat4x3 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
- const float inv = 1.0 / b;
- __retVal[0] = m[0] * inv;
- __retVal[1] = m[1] * inv;
- __retVal[2] = m[2] * inv;
- __retVal[3] = m[3] * inv;
-}
-
-mat4x3 __operator / (const float a, const mat4x3 n)
-{
- //return mat4x3 (a / n[0], a / n[1], a / n[2], a / n[3]);
- const float inv = 1.0 / a;
- __retVal[0] = inv * n[0];
- __retVal[1] = inv * n[1];
- __retVal[2] = inv * n[2];
- __retVal[3] = inv * n[3];
-}
-
-
-mat2x3 __operator - (const mat2x3 m) {
- return mat2x3 (-m[0], -m[1]);
-}
-
-mat2x4 __operator - (const mat2x4 m) {
- return mat2x4 (-m[0], -m[1]);
-}
-
-mat3x2 __operator - (const mat3x2 m) {
- return mat3x2 (-m[0], -m[1], -m[2]);
-}
-
-mat3x4 __operator - (const mat3x4 m) {
- return mat3x4 (-m[0], -m[1], -m[2]);
-}
-
-mat4x2 __operator - (const mat4x2 m) {
- return mat4x2 (-m[0], -m[1], -m[2], -m[3]);
-}
-
-mat4x3 __operator - (const mat4x3 m) {
- return mat4x3 (-m[0], -m[1], -m[2], -m[3]);
-}
-
-
-void __operator -- (inout mat2x3 m) {
- --m[0];
- --m[1];
-}
-
-void __operator -- (inout mat2x4 m) {
- --m[0];
- --m[1];
-}
-
-void __operator -- (inout mat3x2 m) {
- --m[0];
- --m[1];
- --m[2];
-}
-
-void __operator -- (inout mat3x4 m) {
- --m[0];
- --m[1];
- --m[2];
-}
-
-void __operator -- (inout mat4x2 m) {
- --m[0];
- --m[1];
- --m[2];
- --m[3];
-}
-
-void __operator -- (inout mat4x3 m) {
- --m[0];
- --m[1];
- --m[2];
- --m[3];
-}
-
-
-void __operator ++ (inout mat2x3 m) {
- ++m[0];
- ++m[1];
-}
-
-void __operator ++ (inout mat2x4 m) {
- ++m[0];
- ++m[1];
-}
-
-void __operator ++ (inout mat3x2 m) {
- ++m[0];
- ++m[1];
- ++m[2];
-}
-
-void __operator ++ (inout mat3x4 m) {
- ++m[0];
- ++m[1];
- ++m[2];
-}
-
-void __operator ++ (inout mat4x2 m) {
- ++m[0];
- ++m[1];
- ++m[2];
- ++m[3];
-}
-
-void __operator ++ (inout mat4x3 m) {
- ++m[0];
- ++m[1];
- ++m[2];
- ++m[3];
-}
-
diff --git a/src/mesa/slang/library/slang_builtin_120_common.gc b/src/mesa/slang/library/slang_builtin_120_common.gc
deleted file mode 100644
index c6264c3b471..00000000000
--- a/src/mesa/slang/library/slang_builtin_120_common.gc
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.6
- *
- * Copyright (C) 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.
- */
-
-//
-// From Shader Spec, ver. 1.20, rev. 6
-//
-
-//
-// 8.5 Matrix Functions
-//
-
-mat2x3 matrixCompMult (mat2x3 m, mat2x3 n) {
- return mat2x3 (m[0] * n[0], m[1] * n[1]);
-}
-
-mat2x4 matrixCompMult (mat2x4 m, mat2x4 n) {
- return mat2x4 (m[0] * n[0], m[1] * n[1]);
-}
-
-mat3x2 matrixCompMult (mat3x2 m, mat3x2 n) {
- return mat3x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
-}
-
-mat3x4 matrixCompMult (mat3x4 m, mat3x4 n) {
- return mat3x4 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
-}
-
-mat4x2 matrixCompMult (mat4x2 m, mat4x2 n) {
- return mat4x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
-}
-
-mat4x3 matrixCompMult (mat4x3 m, mat4x3 n) {
- return mat4x3 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
-}
-
-mat2 outerProduct (vec2 c, vec2 r) {
- return mat2 (
- c.x * r.x, c.y * r.x,
- c.x * r.y, c.y * r.y
- );
-}
-
-mat3 outerProduct (vec3 c, vec3 r) {
- return mat3 (
- c.x * r.x, c.y * r.x, c.z * r.x,
- c.x * r.y, c.y * r.y, c.z * r.y,
- c.x * r.z, c.y * r.z, c.z * r.z
- );
-}
-
-mat4 outerProduct (vec4 c, vec4 r) {
- return mat4 (
- c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
- c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y,
- c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z,
- c.x * r.w, c.y * r.w, c.z * r.w, c.w * r.w
- );
-}
-
-mat2x3 outerProduct (vec3 c, vec2 r) {
- return mat2x3 (
- c.x * r.x, c.y * r.x, c.z * r.x,
- c.x * r.y, c.y * r.y, c.z * r.y
- );
-}
-
-mat3x2 outerProduct (vec2 c, vec3 r) {
- return mat3x2 (
- c.x * r.x, c.y * r.x,
- c.x * r.y, c.y * r.y,
- c.x * r.z, c.y * r.z
- );
-}
-
-mat2x4 outerProduct (vec4 c, vec2 r) {
- return mat2x4 (
- c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
- c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y
- );
-}
-
-mat4x2 outerProduct (vec2 c, vec4 r) {
- return mat4x2 (
- c.x * r.x, c.y * r.x,
- c.x * r.y, c.y * r.y,
- c.x * r.z, c.y * r.z,
- c.x * r.w, c.y * r.w
- );
-}
-
-mat3x4 outerProduct (vec4 c, vec3 r) {
- return mat3x4 (
- c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
- c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y,
- c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z
- );
-}
-
-mat4x3 outerProduct (vec3 c, vec4 r) {
- return mat4x3 (
- c.x * r.x, c.y * r.x, c.z * r.x,
- c.x * r.y, c.y * r.y, c.z * r.y,
- c.x * r.z, c.y * r.z, c.z * r.z,
- c.x * r.w, c.y * r.w, c.z * r.w
- );
-}
-
-mat2 transpose (mat2 m) {
- return mat2 (
- m[0].x, m[1].x,
- m[0].y, m[1].y
- );
-}
-
-mat3 transpose (mat3 m) {
- return mat3 (
- m[0].x, m[1].x, m[2].x,
- m[0].y, m[1].y, m[2].y,
- m[0].z, m[1].z, m[2].z
- );
-}
-
-mat4 transpose (mat4 m) {
- return mat4 (
- m[0].x, m[1].x, m[2].x, m[3].x,
- m[0].y, m[1].y, m[2].y, m[3].y,
- m[0].z, m[1].z, m[2].z, m[3].z,
- m[0].w, m[1].w, m[2].w, m[3].w
- );
-}
-
-mat2x3 transpose (mat3x2 m) {
- return mat2x3 (
- m[0].x, m[1].x, m[2].x,
- m[0].y, m[1].y, m[2].y
- );
-}
-
-mat3x2 transpose (mat2x3 m) {
- return mat3x2 (
- m[0].x, m[1].x,
- m[0].y, m[1].y,
- m[0].z, m[1].z
- );
-}
-
-mat2x4 transpose (mat4x2 m) {
- return mat2x4 (
- m[0].x, m[1].x, m[2].x, m[3].x,
- m[0].y, m[1].y, m[2].y, m[3].y
- );
-}
-
-mat4x2 transpose (mat2x4 m) {
- return mat4x2 (
- m[0].x, m[1].x,
- m[0].y, m[1].y,
- m[0].z, m[1].z,
- m[0].w, m[1].w
- );
-}
-
-mat3x4 transpose (mat4x3 m) {
- return mat3x4 (
- m[0].x, m[1].x, m[2].x, m[3].x,
- m[0].y, m[1].y, m[2].y, m[3].y,
- m[0].z, m[1].z, m[2].z, m[3].z
- );
-}
-
-mat4x3 transpose (mat3x4 m) {
- return mat4x3 (
- m[0].x, m[1].x, m[2].x,
- m[0].y, m[1].y, m[2].y,
- m[0].z, m[1].z, m[2].z,
- m[0].w, m[1].w, m[2].w
- );
-}
-
diff --git a/src/mesa/slang/library/slang_common_builtin.gc b/src/mesa/slang/library/slang_common_builtin.gc
deleted file mode 100644
index 1f5ddbc1ee2..00000000000
--- a/src/mesa/slang/library/slang_common_builtin.gc
+++ /dev/null
@@ -1,1887 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 2006 Brian Paul All Rights Reserved.
- * Copyright (C) 2008 VMware, 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.
- */
-
-//
-// From Shader Spec, ver. 1.10, rev. 59
-//
-
-// Note: the values assigned to these constants here aren't actually used.
-// They're set by the compiler according to the GL context limits.
-// See slang_simplify.c
-const int gl_MaxLights = 8;
-const int gl_MaxClipPlanes = 6;
-const int gl_MaxTextureUnits = 8;
-const int gl_MaxTextureCoords = 8;
-const int gl_MaxVertexAttribs = 16;
-const int gl_MaxVertexUniformComponents = 512;
-const int gl_MaxVaryingFloats = 32;
-const int gl_MaxVertexTextureImageUnits = 0;
-const int gl_MaxCombinedTextureImageUnits = 2;
-const int gl_MaxTextureImageUnits = 2;
-const int gl_MaxFragmentUniformComponents = 64;
-const int gl_MaxDrawBuffers = 1;
-
-uniform mat4 gl_ModelViewMatrix;
-uniform mat4 gl_ProjectionMatrix;
-uniform mat4 gl_ModelViewProjectionMatrix;
-uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];
-
-uniform mat3 gl_NormalMatrix;
-
-uniform mat4 gl_ModelViewMatrixInverse;
-uniform mat4 gl_ProjectionMatrixInverse;
-uniform mat4 gl_ModelViewProjectionMatrixInverse;
-uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];
-
-uniform mat4 gl_ModelViewMatrixTranspose;
-uniform mat4 gl_ProjectionMatrixTranspose;
-uniform mat4 gl_ModelViewProjectionMatrixTranspose;
-uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];
-
-uniform mat4 gl_ModelViewMatrixInverseTranspose;
-uniform mat4 gl_ProjectionMatrixInverseTranspose;
-uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;
-uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];
-
-uniform float gl_NormalScale;
-
-struct gl_DepthRangeParameters {
- float near;
- float far;
- float diff;
-};
-
-uniform gl_DepthRangeParameters gl_DepthRange;
-
-uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];
-
-struct gl_PointParameters {
- float size;
- float sizeMin;
- float sizeMax;
- float fadeThresholdSize;
- float distanceConstantAttenuation;
- float distanceLinearAttenuation;
- float distanceQuadraticAttenuation;
-};
-
-uniform gl_PointParameters gl_Point;
-
-struct gl_MaterialParameters {
- vec4 emission;
- vec4 ambient;
- vec4 diffuse;
- vec4 specular;
- float shininess;
-};
-
-uniform gl_MaterialParameters gl_FrontMaterial;
-uniform gl_MaterialParameters gl_BackMaterial;
-
-/* NOTE: the order of these fields is significant!
- * See the definition of the lighting state vars such as STATE_SPOT_DIRECTION.
- */
-struct gl_LightSourceParameters {
- vec4 ambient;
- vec4 diffuse;
- vec4 specular;
- vec4 position;
- vec4 halfVector;
- vec3 spotDirection;
- float spotCosCutoff;
-
- float constantAttenuation;
- float linearAttenuation;
- float quadraticAttenuation;
- float spotExponent;
-
- float spotCutoff;
-};
-
-uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
-
-struct gl_LightModelParameters {
- vec4 ambient;
-};
-
-uniform gl_LightModelParameters gl_LightModel;
-
-struct gl_LightModelProducts {
- vec4 sceneColor;
-};
-
-uniform gl_LightModelProducts gl_FrontLightModelProduct;
-uniform gl_LightModelProducts gl_BackLightModelProduct;
-
-struct gl_LightProducts {
- vec4 ambient;
- vec4 diffuse;
- vec4 specular;
-};
-
-uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];
-uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];
-
-uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];
-uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];
-uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];
-uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];
-uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];
-uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];
-uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];
-uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];
-uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];
-
-struct gl_FogParameters {
- vec4 color;
- float density;
- float start;
- float end;
- float scale;
-};
-
-uniform gl_FogParameters gl_Fog;
-
-
-
-
-
-//
-// 8.1 Angle and Trigonometry Functions
-//
-
-//// radians
-
-float radians(const float deg)
-{
- const float c = 3.1415926 / 180.0;
- __asm vec4_multiply __retVal, deg, c;
-}
-
-vec2 radians(const vec2 deg)
-{
- const float c = 3.1415926 / 180.0;
- __asm vec4_multiply __retVal.xy, deg.xy, c.xx;
-}
-
-vec3 radians(const vec3 deg)
-{
- const float c = 3.1415926 / 180.0;
- __asm vec4_multiply __retVal.xyz, deg.xyz, c.xxx;
-}
-
-vec4 radians(const vec4 deg)
-{
- const float c = 3.1415926 / 180.0;
- __asm vec4_multiply __retVal, deg, c.xxxx;
-}
-
-
-//// degrees
-
-float degrees(const float rad)
-{
- const float c = 180.0 / 3.1415926;
- __asm vec4_multiply __retVal, rad, c;
-}
-
-vec2 degrees(const vec2 rad)
-{
- const float c = 180.0 / 3.1415926;
- __asm vec4_multiply __retVal.xy, rad.xy, c.xx;
-}
-
-vec3 degrees(const vec3 rad)
-{
- const float c = 180.0 / 3.1415926;
- __asm vec4_multiply __retVal.xyz, rad.xyz, c.xxx;
-}
-
-vec4 degrees(const vec4 rad)
-{
- const float c = 180.0 / 3.1415926;
- __asm vec4_multiply __retVal, rad, c.xxxx;
-}
-
-
-//// sin
-
-float sin(const float radians)
-{
- __asm float_sine __retVal, radians;
-}
-
-vec2 sin(const vec2 radians)
-{
- __asm float_sine __retVal.x, radians.x;
- __asm float_sine __retVal.y, radians.y;
-}
-
-vec3 sin(const vec3 radians)
-{
- __asm float_sine __retVal.x, radians.x;
- __asm float_sine __retVal.y, radians.y;
- __asm float_sine __retVal.z, radians.z;
-}
-
-vec4 sin(const vec4 radians)
-{
- __asm float_sine __retVal.x, radians.x;
- __asm float_sine __retVal.y, radians.y;
- __asm float_sine __retVal.z, radians.z;
- __asm float_sine __retVal.w, radians.w;
-}
-
-
-//// cos
-
-float cos(const float radians)
-{
- __asm float_cosine __retVal, radians;
-}
-
-vec2 cos(const vec2 radians)
-{
- __asm float_cosine __retVal.x, radians.x;
- __asm float_cosine __retVal.y, radians.y;
-}
-
-vec3 cos(const vec3 radians)
-{
- __asm float_cosine __retVal.x, radians.x;
- __asm float_cosine __retVal.y, radians.y;
- __asm float_cosine __retVal.z, radians.z;
-}
-
-vec4 cos(const vec4 radians)
-{
- __asm float_cosine __retVal.x, radians.x;
- __asm float_cosine __retVal.y, radians.y;
- __asm float_cosine __retVal.z, radians.z;
- __asm float_cosine __retVal.w, radians.w;
-}
-
-
-
-//// tan
-
-float tan(const float angle)
-{
- const float s = sin(angle);
- const float c = cos(angle);
- return s / c;
-}
-
-vec2 tan(const vec2 angle)
-{
- const vec2 s = sin(angle);
- const vec2 c = cos(angle);
- return s / c;
-}
-
-vec3 tan(const vec3 angle)
-{
- const vec3 s = sin(angle);
- const vec3 c = cos(angle);
- return s / c;
-}
-
-vec4 tan(const vec4 angle)
-{
- const vec4 s = sin(angle);
- const vec4 c = cos(angle);
- return s / c;
-}
-
-
-
-float asin(const float x)
-{
- const float a0 = 1.5707288; // PI/2?
- const float a1 = -0.2121144;
- const float a2 = 0.0742610;
- //const float a3 = -0.0187293;
- const float halfPi = 3.1415926 * 0.5;
- const float y = abs(x);
- // three terms seem to be enough:
- __retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + a2 * y))) * sign(x);
- // otherwise, try four:
- //__retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + y * (a2 + y * a3)))) * sign(x);
-}
-
-vec2 asin(const vec2 v)
-{
- __retVal.x = asin(v.x);
- __retVal.y = asin(v.y);
-}
-
-vec3 asin(const vec3 v)
-{
- __retVal.x = asin(v.x);
- __retVal.y = asin(v.y);
- __retVal.z = asin(v.z);
-}
-
-vec4 asin(const vec4 v)
-{
- __retVal.x = asin(v.x);
- __retVal.y = asin(v.y);
- __retVal.z = asin(v.z);
- __retVal.w = asin(v.w);
-}
-
-float acos(const float x)
-{
- const float halfPi = 3.1415926 * 0.5;
- __retVal = halfPi - asin(x);
-}
-
-vec2 acos(const vec2 v)
-{
- __retVal.x = acos(v.x);
- __retVal.y = acos(v.y);
-}
-
-vec3 acos(const vec3 v)
-{
- __retVal.x = acos(v.x);
- __retVal.y = acos(v.y);
- __retVal.z = acos(v.z);
-}
-
-vec4 acos(const vec4 v)
-{
- __retVal.x = acos(v.x);
- __retVal.y = acos(v.y);
- __retVal.z = acos(v.z);
- __retVal.w = acos(v.w);
-}
-
-float atan(const float x)
-{
- __retVal = asin(x * inversesqrt(x * x + 1.0));
-}
-
-vec2 atan(const vec2 y_over_x)
-{
- __retVal.x = atan(y_over_x.x);
- __retVal.y = atan(y_over_x.y);
-}
-
-vec3 atan(const vec3 y_over_x)
-{
- __retVal.x = atan(y_over_x.x);
- __retVal.y = atan(y_over_x.y);
- __retVal.z = atan(y_over_x.z);
-}
-
-vec4 atan(const vec4 y_over_x)
-{
- __retVal.x = atan(y_over_x.x);
- __retVal.y = atan(y_over_x.y);
- __retVal.z = atan(y_over_x.z);
- __retVal.w = atan(y_over_x.w);
-}
-
-float atan(const float y, const float x)
-{
- float r;
- if (abs(x) > 1.0e-4) {
- r = atan(y / x);
- if (x < 0.0) {
- r = r + 3.141593 - 6.283186 * float(y < 0.0);
- }
- }
- else {
- r = sign(y) * 1.5707965; // pi/2
- }
- return r;
-}
-
-vec2 atan(const vec2 u, const vec2 v)
-{
- __retVal.x = atan(u.x, v.x);
- __retVal.y = atan(u.y, v.y);
-}
-
-vec3 atan(const vec3 u, const vec3 v)
-{
- __retVal.x = atan(u.x, v.x);
- __retVal.y = atan(u.y, v.y);
- __retVal.z = atan(u.z, v.z);
-}
-
-vec4 atan(const vec4 u, const vec4 v)
-{
- __retVal.x = atan(u.x, v.x);
- __retVal.y = atan(u.y, v.y);
- __retVal.z = atan(u.z, v.z);
- __retVal.w = atan(u.w, v.w);
-}
-
-
-//
-// 8.2 Exponential Functions
-//
-
-//// pow
-
-float pow(const float a, const float b)
-{
- __asm float_power __retVal, a, b;
-}
-
-vec2 pow(const vec2 a, const vec2 b)
-{
- __asm float_power __retVal.x, a.x, b.x;
- __asm float_power __retVal.y, a.y, b.y;
-}
-
-vec3 pow(const vec3 a, const vec3 b)
-{
- __asm float_power __retVal.x, a.x, b.x;
- __asm float_power __retVal.y, a.y, b.y;
- __asm float_power __retVal.z, a.z, b.z;
-}
-
-vec4 pow(const vec4 a, const vec4 b)
-{
- __asm float_power __retVal.x, a.x, b.x;
- __asm float_power __retVal.y, a.y, b.y;
- __asm float_power __retVal.z, a.z, b.z;
- __asm float_power __retVal.w, a.w, b.w;
-}
-
-
-//// exp
-
-float exp(const float a)
-{
- // NOTE: log2(e) = 1.44269502
- float t = a * 1.44269502;
- __asm float_exp2 __retVal, t;
-}
-
-vec2 exp(const vec2 a)
-{
- vec2 t = a * 1.44269502;
- __asm float_exp2 __retVal.x, t.x;
- __asm float_exp2 __retVal.y, t.y;
-}
-
-vec3 exp(const vec3 a)
-{
- vec3 t = a * 1.44269502;
- __asm float_exp2 __retVal.x, t.x;
- __asm float_exp2 __retVal.y, t.y;
- __asm float_exp2 __retVal.z, t.z;
-}
-
-vec4 exp(const vec4 a)
-{
- vec4 t = a * 1.44269502;
- __asm float_exp2 __retVal.x, t.x;
- __asm float_exp2 __retVal.y, t.y;
- __asm float_exp2 __retVal.z, t.z;
- __asm float_exp2 __retVal.w, t.w;
-}
-
-
-
-//// log2
-
-float log2(const float x)
-{
- __asm float_log2 __retVal, x;
-}
-
-vec2 log2(const vec2 v)
-{
- __asm float_log2 __retVal.x, v.x;
- __asm float_log2 __retVal.y, v.y;
-}
-
-vec3 log2(const vec3 v)
-{
- __asm float_log2 __retVal.x, v.x;
- __asm float_log2 __retVal.y, v.y;
- __asm float_log2 __retVal.z, v.z;
-}
-
-vec4 log2(const vec4 v)
-{
- __asm float_log2 __retVal.x, v.x;
- __asm float_log2 __retVal.y, v.y;
- __asm float_log2 __retVal.z, v.z;
- __asm float_log2 __retVal.w, v.w;
-}
-
-
-//// log (natural log)
-
-float log(const float x)
-{
- // note: logBaseB(x) = logBaseN(x) / logBaseN(B)
- // compute log(x) = log2(x) / log2(e)
- // c = 1.0 / log2(e) = 0.693147181
- const float c = 0.693147181;
- return log2(x) * c;
-}
-
-vec2 log(const vec2 v)
-{
- const float c = 0.693147181;
- return log2(v) * c;
-}
-
-vec3 log(const vec3 v)
-{
- const float c = 0.693147181;
- return log2(v) * c;
-}
-
-vec4 log(const vec4 v)
-{
- const float c = 0.693147181;
- return log2(v) * c;
-}
-
-
-//// exp2
-
-float exp2(const float a)
-{
- __asm float_exp2 __retVal, a;
-}
-
-vec2 exp2(const vec2 a)
-{
- __asm float_exp2 __retVal.x, a.x;
- __asm float_exp2 __retVal.y, a.y;
-}
-
-vec3 exp2(const vec3 a)
-{
- __asm float_exp2 __retVal.x, a.x;
- __asm float_exp2 __retVal.y, a.y;
- __asm float_exp2 __retVal.z, a.z;
-}
-
-vec4 exp2(const vec4 a)
-{
- __asm float_exp2 __retVal.x, a.x;
- __asm float_exp2 __retVal.y, a.y;
- __asm float_exp2 __retVal.z, a.z;
- __asm float_exp2 __retVal.w, a.w;
-}
-
-
-//// sqrt
-
-float sqrt(const float x)
-{
- const float nx = -x;
- float r;
- __asm float_rsq r, x;
- r = r * x;
- __asm vec4_cmp __retVal, nx, r, 0.0;
-}
-
-vec2 sqrt(const vec2 x)
-{
- const vec2 nx = -x, zero = vec2(0.0);
- vec2 r;
- __asm float_rsq r.x, x.x;
- __asm float_rsq r.y, x.y;
- r = r * x;
- __asm vec4_cmp __retVal, nx, r, zero;
-}
-
-vec3 sqrt(const vec3 x)
-{
- const vec3 nx = -x, zero = vec3(0.0);
- vec3 r;
- __asm float_rsq r.x, x.x;
- __asm float_rsq r.y, x.y;
- __asm float_rsq r.z, x.z;
- r = r * x;
- __asm vec4_cmp __retVal, nx, r, zero;
-}
-
-vec4 sqrt(const vec4 x)
-{
- const vec4 nx = -x, zero = vec4(0.0);
- vec4 r;
- __asm float_rsq r.x, x.x;
- __asm float_rsq r.y, x.y;
- __asm float_rsq r.z, x.z;
- __asm float_rsq r.w, x.w;
- r = r * x;
- __asm vec4_cmp __retVal, nx, r, zero;
-}
-
-
-//// inversesqrt
-
-float inversesqrt(const float x)
-{
- __asm float_rsq __retVal.x, x;
-}
-
-vec2 inversesqrt(const vec2 v)
-{
- __asm float_rsq __retVal.x, v.x;
- __asm float_rsq __retVal.y, v.y;
-}
-
-vec3 inversesqrt(const vec3 v)
-{
- __asm float_rsq __retVal.x, v.x;
- __asm float_rsq __retVal.y, v.y;
- __asm float_rsq __retVal.z, v.z;
-}
-
-vec4 inversesqrt(const vec4 v)
-{
- __asm float_rsq __retVal.x, v.x;
- __asm float_rsq __retVal.y, v.y;
- __asm float_rsq __retVal.z, v.z;
- __asm float_rsq __retVal.w, v.w;
-}
-
-
-//// normalize
-
-float normalize(const float x)
-{
- __retVal = 1.0;
-}
-
-vec2 normalize(const vec2 v)
-{
- const float s = inversesqrt(dot(v, v));
- __asm vec4_multiply __retVal.xy, v, s;
-}
-
-vec3 normalize(const vec3 v)
-{
-// const float s = inversesqrt(dot(v, v));
-// __retVal = v * s;
-// XXX note, we _could_ use __retVal.w instead of tmp and save a
-// register, but that's actually a compilation error because v is a vec3
-// and the .w suffix is illegal. Oh well.
- float tmp;
- __asm vec3_dot tmp, v, v;
- __asm float_rsq tmp, tmp;
- __asm vec4_multiply __retVal.xyz, v, tmp;
-}
-
-vec4 normalize(const vec4 v)
-{
- float tmp;
- __asm vec4_dot tmp, v, v;
- __asm float_rsq tmp, tmp;
- __asm vec4_multiply __retVal.xyz, v, tmp;
-}
-
-
-
-//
-// 8.3 Common Functions
-//
-
-
-//// abs
-
-float abs(const float a)
-{
- __asm vec4_abs __retVal, a;
-}
-
-vec2 abs(const vec2 a)
-{
- __asm vec4_abs __retVal.xy, a;
-}
-
-vec3 abs(const vec3 a)
-{
- __asm vec4_abs __retVal.xyz, a;
-}
-
-vec4 abs(const vec4 a)
-{
- __asm vec4_abs __retVal, a;
-}
-
-
-//// sign
-
-float sign(const float x)
-{
- float p, n;
- __asm vec4_sgt p, x, 0.0; // p = (x > 0)
- __asm vec4_sgt n, 0.0, x; // n = (x < 0)
- __asm vec4_subtract __retVal, p, n; // sign = p - n
-}
-
-vec2 sign(const vec2 v)
-{
- vec2 p, n;
- __asm vec4_sgt p.xy, v, 0.0;
- __asm vec4_sgt n.xy, 0.0, v;
- __asm vec4_subtract __retVal.xy, p, n;
-}
-
-vec3 sign(const vec3 v)
-{
- vec3 p, n;
- __asm vec4_sgt p.xyz, v, 0.0;
- __asm vec4_sgt n.xyz, 0.0, v;
- __asm vec4_subtract __retVal.xyz, p, n;
-}
-
-vec4 sign(const vec4 v)
-{
- vec4 p, n;
- __asm vec4_sgt p, v, 0.0;
- __asm vec4_sgt n, 0.0, v;
- __asm vec4_subtract __retVal, p, n;
-}
-
-
-//// floor
-
-float floor(const float a)
-{
- __asm vec4_floor __retVal, a;
-}
-
-vec2 floor(const vec2 a)
-{
- __asm vec4_floor __retVal.xy, a;
-}
-
-vec3 floor(const vec3 a)
-{
- __asm vec4_floor __retVal.xyz, a;
-}
-
-vec4 floor(const vec4 a)
-{
- __asm vec4_floor __retVal, a;
-}
-
-
-//// ceil
-
-float ceil(const float a)
-{
- // XXX this could be improved
- float b = -a;
- __asm vec4_floor b, b;
- __retVal = -b;
-}
-
-vec2 ceil(const vec2 a)
-{
- vec2 b = -a;
- __asm vec4_floor b, b;
- __retVal.xy = -b;
-}
-
-vec3 ceil(const vec3 a)
-{
- vec3 b = -a;
- __asm vec4_floor b, b;
- __retVal.xyz = -b;
-}
-
-vec4 ceil(const vec4 a)
-{
- vec4 b = -a;
- __asm vec4_floor b, b;
- __retVal = -b;
-}
-
-
-//// fract
-
-float fract(const float a)
-{
- __asm vec4_frac __retVal, a;
-}
-
-vec2 fract(const vec2 a)
-{
- __asm vec4_frac __retVal.xy, a;
-}
-
-vec3 fract(const vec3 a)
-{
- __asm vec4_frac __retVal.xyz, a;
-}
-
-vec4 fract(const vec4 a)
-{
- __asm vec4_frac __retVal, a;
-}
-
-
-//// mod (very untested!)
-
-float mod(const float a, const float b)
-{
- float oneOverB;
- __asm float_rcp oneOverB, b;
- __retVal = a - b * floor(a * oneOverB);
-}
-
-vec2 mod(const vec2 a, const float b)
-{
- float oneOverB;
- __asm float_rcp oneOverB, b;
- __retVal.xy = a - b * floor(a * oneOverB);
-}
-
-vec3 mod(const vec3 a, const float b)
-{
- float oneOverB;
- __asm float_rcp oneOverB, b;
- __retVal.xyz = a - b * floor(a * oneOverB);
-}
-
-vec4 mod(const vec4 a, const float b)
-{
- float oneOverB;
- __asm float_rcp oneOverB, b;
- __retVal = a - b * floor(a * oneOverB);
-}
-
-vec2 mod(const vec2 a, const vec2 b)
-{
- vec2 oneOverB;
- __asm float_rcp oneOverB.x, b.x;
- __asm float_rcp oneOverB.y, b.y;
- __retVal = a - b * floor(a * oneOverB);
-}
-
-vec3 mod(const vec3 a, const vec3 b)
-{
- vec3 oneOverB;
- __asm float_rcp oneOverB.x, b.x;
- __asm float_rcp oneOverB.y, b.y;
- __asm float_rcp oneOverB.z, b.z;
- __retVal = a - b * floor(a * oneOverB);
-}
-
-vec4 mod(const vec4 a, const vec4 b)
-{
- vec4 oneOverB;
- __asm float_rcp oneOverB.x, b.x;
- __asm float_rcp oneOverB.y, b.y;
- __asm float_rcp oneOverB.z, b.z;
- __asm float_rcp oneOverB.w, b.w;
- __retVal = a - b * floor(a * oneOverB);
-}
-
-
-//// min
-
-float min(const float a, const float b)
-{
- __asm vec4_min __retVal, a, b;
-}
-
-vec2 min(const vec2 a, const vec2 b)
-{
- __asm vec4_min __retVal.xy, a.xy, b.xy;
-}
-
-vec3 min(const vec3 a, const vec3 b)
-{
- __asm vec4_min __retVal.xyz, a.xyz, b.xyz;
-}
-
-vec4 min(const vec4 a, const vec4 b)
-{
- __asm vec4_min __retVal, a, b;
-}
-
-vec2 min(const vec2 a, const float b)
-{
- __asm vec4_min __retVal, a.xy, b;
-}
-
-vec3 min(const vec3 a, const float b)
-{
- __asm vec4_min __retVal, a.xyz, b;
-}
-
-vec4 min(const vec4 a, const float b)
-{
- __asm vec4_min __retVal, a, b;
-}
-
-
-//// max
-
-float max(const float a, const float b)
-{
- __asm vec4_max __retVal, a, b;
-}
-
-vec2 max(const vec2 a, const vec2 b)
-{
- __asm vec4_max __retVal.xy, a.xy, b.xy;
-}
-
-vec3 max(const vec3 a, const vec3 b)
-{
- __asm vec4_max __retVal.xyz, a.xyz, b.xyz;
-}
-
-vec4 max(const vec4 a, const vec4 b)
-{
- __asm vec4_max __retVal, a, b;
-}
-
-vec2 max(const vec2 a, const float b)
-{
- __asm vec4_max __retVal, a.xy, b;
-}
-
-vec3 max(const vec3 a, const float b)
-{
- __asm vec4_max __retVal, a.xyz, b;
-}
-
-vec4 max(const vec4 a, const float b)
-{
- __asm vec4_max __retVal, a, b;
-}
-
-
-//// clamp
-
-float clamp(const float val, const float minVal, const float maxVal)
-{
- __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec2 clamp(const vec2 val, const float minVal, const float maxVal)
-{
- __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec3 clamp(const vec3 val, const float minVal, const float maxVal)
-{
- __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec4 clamp(const vec4 val, const float minVal, const float maxVal)
-{
- __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec2 clamp(const vec2 val, const vec2 minVal, const vec2 maxVal)
-{
- __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec3 clamp(const vec3 val, const vec3 minVal, const vec3 maxVal)
-{
- __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec4 clamp(const vec4 val, const vec4 minVal, const vec4 maxVal)
-{
- __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-
-//// mix
-
-float mix(const float x, const float y, const float a)
-{
- __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec2 mix(const vec2 x, const vec2 y, const float a)
-{
- __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec3 mix(const vec3 x, const vec3 y, const float a)
-{
- __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec4 mix(const vec4 x, const vec4 y, const float a)
-{
- __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec2 mix(const vec2 x, const vec2 y, const vec2 a)
-{
- __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec3 mix(const vec3 x, const vec3 y, const vec3 a)
-{
- __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec4 mix(const vec4 x, const vec4 y, const vec4 a)
-{
- __asm vec4_lrp __retVal, a, y, x;
-}
-
-
-//// step
-
-float step(const float edge, const float x)
-{
- __asm vec4_sge __retVal, x, edge;
-}
-
-vec2 step(const vec2 edge, const vec2 x)
-{
- __asm vec4_sge __retVal.xy, x, edge;
-}
-
-vec3 step(const vec3 edge, const vec3 x)
-{
- __asm vec4_sge __retVal.xyz, x, edge;
-}
-
-vec4 step(const vec4 edge, const vec4 x)
-{
- __asm vec4_sge __retVal, x, edge;
-}
-
-vec2 step(const float edge, const vec2 v)
-{
- __asm vec4_sge __retVal.xy, v, edge;
-}
-
-vec3 step(const float edge, const vec3 v)
-{
- __asm vec4_sge __retVal.xyz, v, edge;
-}
-
-vec4 step(const float edge, const vec4 v)
-{
- __asm vec4_sge __retVal, v, edge;
-}
-
-
-//// smoothstep
-
-float smoothstep(const float edge0, const float edge1, const float x)
-{
- float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
- return t * t * (3.0 - 2.0 * t);
-}
-
-vec2 smoothstep(const vec2 edge0, const vec2 edge1, const vec2 v)
-{
- vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
- return t * t * (3.0 - 2.0 * t);
-}
-
-vec3 smoothstep(const vec3 edge0, const vec3 edge1, const vec3 v)
-{
- vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
- return t * t * (3.0 - 2.0 * t);
-}
-
-vec4 smoothstep(const vec4 edge0, const vec4 edge1, const vec4 v)
-{
- vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
- return t * t * (3.0 - 2.0 * t);
-}
-
-vec2 smoothstep(const float edge0, const float edge1, const vec2 v)
-{
- vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
- return t * t * (3.0 - 2.0 * t);
-}
-
-vec3 smoothstep(const float edge0, const float edge1, const vec3 v)
-{
- vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
- return t * t * (3.0 - 2.0 * t);
-}
-
-vec4 smoothstep(const float edge0, const float edge1, const vec4 v)
-{
- vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
- return t * t * (3.0 - 2.0 * t);
-}
-
-
-
-//
-// 8.4 Geometric Functions
-//
-
-
-//// length
-
-float length(const float x)
-{
- return abs(x);
-}
-
-float length(const vec2 v)
-{
- float r;
- const float p = dot(v, v); // p = v.x * v.x + v.y * v.y
- __asm float_rsq r, p; // r = 1 / sqrt(p)
- __retVal = p * r; // p * r = sqrt(p);
-}
-
-float length(const vec3 v)
-{
- float r;
- const float p = dot(v, v); // p = v.x * v.x + v.y * v.y + v.z * v.z
- __asm float_rsq r, p; // r = 1 / sqrt(p)
- __retVal = p * r; // p * r = sqrt(p);
-}
-
-float length(const vec4 v)
-{
- float r;
- const float p = dot(v, v); // p = v.x * v.x + v.y * v.y + ...
- __asm float_rsq r, p; // r = 1 / sqrt(p)
- __retVal = p * r; // p * r = sqrt(p);
-}
-
-
-//// distance
-
-float distance(const float x, const float y)
-{
- const float d = x - y;
- __retVal = length(d);
-}
-
-float distance(const vec2 v, const vec2 u)
-{
- const vec2 d2 = v - u;
- __retVal = length(d2);
-}
-
-float distance(const vec3 v, const vec3 u)
-{
- const vec3 d3 = v - u;
- __retVal = length(d3);
-}
-
-float distance(const vec4 v, const vec4 u)
-{
- const vec4 d4 = v - u;
- __retVal = length(d4);
-}
-
-
-//// cross
-
-vec3 cross(const vec3 v, const vec3 u)
-{
- __asm vec3_cross __retVal.xyz, v, u;
-}
-
-
-//// faceforward
-
-float faceforward(const float N, const float I, const float Nref)
-{
- // this could probably be done better
- const float d = dot(Nref, I);
- float s;
- __asm vec4_sgt s, 0.0, d; // s = (0.0 > d) ? 1 : 0
- return mix(-N, N, s);
-}
-
-vec2 faceforward(const vec2 N, const vec2 I, const vec2 Nref)
-{
- // this could probably be done better
- const float d = dot(Nref, I);
- float s;
- __asm vec4_sgt s, 0.0, d; // s = (0.0 > d) ? 1 : 0
- return mix(-N, N, s);
-}
-
-vec3 faceforward(const vec3 N, const vec3 I, const vec3 Nref)
-{
- // this could probably be done better
- const float d = dot(Nref, I);
- float s;
- __asm vec4_sgt s, 0.0, d; // s = (0.0 > d) ? 1 : 0
- return mix(-N, N, s);
-}
-
-vec4 faceforward(const vec4 N, const vec4 I, const vec4 Nref)
-{
- // this could probably be done better
- const float d = dot(Nref, I);
- float s;
- __asm vec4_sgt s, 0.0, d; // s = (0.0 > d) ? 1 : 0
- return mix(-N, N, s);
-}
-
-
-//// reflect
-
-float reflect(const float I, const float N)
-{
- return I - 2.0 * dot(N, I) * N;
-}
-
-vec2 reflect(const vec2 I, const vec2 N)
-{
- return I - 2.0 * dot(N, I) * N;
-}
-
-vec3 reflect(const vec3 I, const vec3 N)
-{
- return I - 2.0 * dot(N, I) * N;
-}
-
-vec4 reflect(const vec4 I, const vec4 N)
-{
- return I - 2.0 * dot(N, I) * N;
-}
-
-//// refract
-
-float refract(const float I, const float N, const float eta)
-{
- float n_dot_i = dot(N, I);
- float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
- float retval;
- if (k < 0.0)
- retval = 0.0;
- else
- retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
- return retval;
-}
-
-vec2 refract(const vec2 I, const vec2 N, const float eta)
-{
- float n_dot_i = dot(N, I);
- float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
- vec2 retval;
- if (k < 0.0)
- retval = vec2(0.0);
- else
- retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
- return retval;
-}
-
-vec3 refract(const vec3 I, const vec3 N, const float eta)
-{
- float n_dot_i = dot(N, I);
- float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
- vec3 retval;
- if (k < 0.0)
- retval = vec3(0.0);
- else
- retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
- return retval;
-}
-
-vec4 refract(const vec4 I, const vec4 N, const float eta)
-{
- float n_dot_i = dot(N, I);
- float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
- vec4 retval;
- if (k < 0.0)
- retval = vec4(0.0);
- else
- retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
- return retval;
-}
-
-
-
-
-//
-// 8.5 Matrix Functions
-//
-
-mat2 matrixCompMult (mat2 m, mat2 n) {
- return mat2 (m[0] * n[0], m[1] * n[1]);
-}
-
-mat3 matrixCompMult (mat3 m, mat3 n) {
- return mat3 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
-}
-
-mat4 matrixCompMult (mat4 m, mat4 n) {
- return mat4 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
-}
-
-
-
-
-//
-// 8.6 Vector Relational Functions
-//
-
-//// lessThan
-
-bvec2 lessThan(const vec2 u, const vec2 v)
-{
- __asm vec4_slt __retVal.xy, u, v;
-}
-
-bvec3 lessThan(const vec3 u, const vec3 v)
-{
- __asm vec4_slt __retVal.xyz, u, v;
-}
-
-bvec4 lessThan(const vec4 u, const vec4 v)
-{
- __asm vec4_slt __retVal, u, v;
-}
-
-bvec2 lessThan(const ivec2 u, const ivec2 v)
-{
- __asm vec4_slt __retVal.xy, u, v;
-}
-
-bvec3 lessThan(const ivec3 u, const ivec3 v)
-{
- __asm vec4_slt __retVal.xyz, u, v;
-}
-
-bvec4 lessThan(const ivec4 u, const ivec4 v)
-{
- __asm vec4_slt __retVal, u, v;
-}
-
-
-//// lessThanEqual
-
-bvec2 lessThanEqual(const vec2 u, const vec2 v)
-{
- __asm vec4_sle __retVal.xy, u, v;
-}
-
-bvec3 lessThanEqual(const vec3 u, const vec3 v)
-{
- __asm vec4_sle __retVal.xyz, u, v;
-}
-
-bvec4 lessThanEqual(const vec4 u, const vec4 v)
-{
- __asm vec4_sle __retVal, u, v;
-}
-
-bvec2 lessThanEqual(const ivec2 u, const ivec2 v)
-{
- __asm vec4_sle __retVal.xy, u, v;
-}
-
-bvec3 lessThanEqual(const ivec3 u, const ivec3 v)
-{
- __asm vec4_sle __retVal.xyz, u, v;
-}
-
-bvec4 lessThanEqual(const ivec4 u, const ivec4 v)
-{
- __asm vec4_sle __retVal, u, v;
-}
-
-
-//// greaterThan
-
-bvec2 greaterThan(const vec2 u, const vec2 v)
-{
- __asm vec4_sgt __retVal.xy, u, v;
-}
-
-bvec3 greaterThan(const vec3 u, const vec3 v)
-{
- __asm vec4_sgt __retVal.xyz, u, v;
-}
-
-bvec4 greaterThan(const vec4 u, const vec4 v)
-{
- __asm vec4_sgt __retVal, u, v;
-}
-
-bvec2 greaterThan(const ivec2 u, const ivec2 v)
-{
- __asm vec4_sgt __retVal.xy, u.xy, v.xy;
-}
-
-bvec3 greaterThan(const ivec3 u, const ivec3 v)
-{
- __asm vec4_sgt __retVal.xyz, u, v;
-}
-
-bvec4 greaterThan(const ivec4 u, const ivec4 v)
-{
- __asm vec4_sgt __retVal, u, v;
-}
-
-
-//// greaterThanEqual
-
-bvec2 greaterThanEqual(const vec2 u, const vec2 v)
-{
- __asm vec4_sge __retVal.xy, u, v;
-}
-
-bvec3 greaterThanEqual(const vec3 u, const vec3 v)
-{
- __asm vec4_sge __retVal.xyz, u, v;
-}
-
-bvec4 greaterThanEqual(const vec4 u, const vec4 v)
-{
- __asm vec4_sge __retVal, u, v;
-}
-
-bvec2 greaterThanEqual(const ivec2 u, const ivec2 v)
-{
- __asm vec4_sge __retVal.xy, u, v;
-}
-
-bvec3 greaterThanEqual(const ivec3 u, const ivec3 v)
-{
- __asm vec4_sge __retVal.xyz, u, v;
-}
-
-bvec4 greaterThanEqual(const ivec4 u, const ivec4 v)
-{
- __asm vec4_sge __retVal, u, v;
-}
-
-
-//// equal
-
-bvec2 equal(const vec2 u, const vec2 v)
-{
- __asm vec4_seq __retVal.xy, u, v;
-}
-
-bvec3 equal(const vec3 u, const vec3 v)
-{
- __asm vec4_seq __retVal.xyz, u, v;
-}
-
-bvec4 equal(const vec4 u, const vec4 v)
-{
- __asm vec4_seq __retVal, u, v;
-}
-
-bvec2 equal(const ivec2 u, const ivec2 v)
-{
- __asm vec4_seq __retVal.xy, u, v;
-}
-
-bvec3 equal(const ivec3 u, const ivec3 v)
-{
- __asm vec4_seq __retVal.xyz, u, v;
-}
-
-bvec4 equal(const ivec4 u, const ivec4 v)
-{
- __asm vec4_seq __retVal, u, v;
-}
-
-bvec2 equal(const bvec2 u, const bvec2 v)
-{
- __asm vec4_seq __retVal.xy, u, v;
-}
-
-bvec3 equal(const bvec3 u, const bvec3 v)
-{
- __asm vec4_seq __retVal.xyz, u, v;
-}
-
-bvec4 equal(const bvec4 u, const bvec4 v)
-{
- __asm vec4_seq __retVal, u, v;
-}
-
-
-
-
-//// notEqual
-
-bvec2 notEqual(const vec2 u, const vec2 v)
-{
- __asm vec4_sne __retVal.xy, u, v;
-}
-
-bvec3 notEqual(const vec3 u, const vec3 v)
-{
- __asm vec4_sne __retVal.xyz, u, v;
-}
-
-bvec4 notEqual(const vec4 u, const vec4 v)
-{
- __asm vec4_sne __retVal, u, v;
-}
-
-bvec2 notEqual(const ivec2 u, const ivec2 v)
-{
- __asm vec4_sne __retVal.xy, u, v;
-}
-
-bvec3 notEqual(const ivec3 u, const ivec3 v)
-{
- __asm vec4_sne __retVal.xyz, u, v;
-}
-
-bvec4 notEqual(const ivec4 u, const ivec4 v)
-{
- __asm vec4_sne __retVal, u, v;
-}
-
-bvec2 notEqual(const bvec2 u, const bvec2 v)
-{
- __asm vec4_sne __retVal.xy, u, v;
-}
-
-bvec3 notEqual(const bvec3 u, const bvec3 v)
-{
- __asm vec4_sne __retVal.xyz, u, v;
-}
-
-bvec4 notEqual(const bvec4 u, const bvec4 v)
-{
- __asm vec4_sne __retVal, u, v;
-}
-
-
-
-//// any
-
-bool any(const bvec2 v)
-{
- float sum;
- __asm vec4_add sum.x, v.x, v.y;
- __asm vec4_sne __retVal.x, sum.x, 0.0;
-}
-
-bool any(const bvec3 v)
-{
- float sum;
- __asm vec4_add sum.x, v.x, v.y;
- __asm vec4_add sum.x, sum.x, v.z;
- __asm vec4_sne __retVal.x, sum.x, 0.0;
-}
-
-bool any(const bvec4 v)
-{
- float sum;
- __asm vec4_add sum.x, v.x, v.y;
- __asm vec4_add sum.x, sum.x, v.z;
- __asm vec4_add sum.x, sum.x, v.w;
- __asm vec4_sne __retVal.x, sum.x, 0.0;
-}
-
-
-//// all
-
-bool all (const bvec2 v)
-{
- float prod;
- __asm vec4_multiply prod, v.x, v.y;
- __asm vec4_sne __retVal, prod, 0.0;
-}
-
-bool all (const bvec3 v)
-{
- float prod;
- __asm vec4_multiply prod, v.x, v.y;
- __asm vec4_multiply prod, prod, v.z;
- __asm vec4_sne __retVal, prod, 0.0;
-}
-
-bool all (const bvec4 v)
-{
- float prod;
- __asm vec4_multiply prod, v.x, v.y;
- __asm vec4_multiply prod, prod, v.z;
- __asm vec4_multiply prod, prod, v.w;
- __asm vec4_sne __retVal, prod, 0.0;
-}
-
-
-
-//// not
-
-bvec2 not (const bvec2 v)
-{
- __asm vec4_seq __retVal.xy, v, 0.0;
-}
-
-bvec3 not (const bvec3 v)
-{
- __asm vec4_seq __retVal.xyz, v, 0.0;
-}
-
-bvec4 not (const bvec4 v)
-{
- __asm vec4_seq __retVal, v, 0.0;
-}
-
-
-
-//// Texture Lookup Functions (for both fragment and vertex shaders)
-
-vec4 texture1D(const sampler1D sampler, const float coord)
-{
- __asm vec4_tex_1d __retVal, sampler, coord;
-}
-
-vec4 texture1DProj(const sampler1D sampler, const vec2 coord)
-{
- // need to swizzle .y into .w
- __asm vec4_tex_1d_proj __retVal, sampler, coord.xyyy;
-}
-
-vec4 texture1DProj(const sampler1D sampler, const vec4 coord)
-{
- __asm vec4_tex_1d_proj __retVal, sampler, coord;
-}
-
-
-vec4 texture2D(const sampler2D sampler, const vec2 coord)
-{
- __asm vec4_tex_2d __retVal, sampler, coord;
-}
-
-vec4 texture2DProj(const sampler2D sampler, const vec3 coord)
-{
- // need to swizzle 'z' into 'w'.
- __asm vec4_tex_2d_proj __retVal, sampler, coord.xyzz;
-}
-
-vec4 texture2DProj(const sampler2D sampler, const vec4 coord)
-{
- __asm vec4_tex_2d_proj __retVal, sampler, coord;
-}
-
-
-vec4 texture3D(const sampler3D sampler, const vec3 coord)
-{
- __asm vec4_tex_3d __retVal, sampler, coord;
-}
-
-vec4 texture3DProj(const sampler3D sampler, const vec4 coord)
-{
- __asm vec4_tex_3d_proj __retVal, sampler, coord;
-}
-
-
-vec4 textureCube(const samplerCube sampler, const vec3 coord)
-{
- __asm vec4_tex_cube __retVal, sampler, coord;
-}
-
-
-
-vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord)
-{
- __asm vec4_tex_1d_shadow __retVal, sampler, coord;
-}
-
-vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord)
-{
- // .s and .p will be divided by .q
- __asm vec4_tex_1d_proj_shadow __retVal, sampler, coord;
-}
-
-vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord)
-{
- __asm vec4_tex_2d_shadow __retVal, sampler, coord;
-}
-
-vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord)
-{
- // .s, .t and .p will be divided by .q
- __asm vec4_tex_2d_proj_shadow __retVal, sampler, coord;
-}
-
-
-//// GL_ARB_texture_rectangle:
-vec4 texture2DRect(const sampler2DRect sampler, const vec2 coord)
-{
- __asm vec4_tex_rect __retVal, sampler, coord;
-}
-
-vec4 texture2DRectProj(const sampler2DRect sampler, const vec3 coord)
-{
- // need to swizzle .y into .w
- __asm vec4_tex_rect_proj __retVal, sampler, coord.xyzz;
-}
-
-vec4 texture2DRectProj(const sampler2DRect sampler, const vec4 coord)
-{
- __asm vec4_tex_rect_proj __retVal, sampler, ccoord;
-}
-
-vec4 shadow2DRect(const sampler2DRectShadow sampler, const vec3 coord)
-{
- __asm vec4_tex_rect_shadow __retVal, sampler, coord;
-}
-
-vec4 shadow2DRectProj(const sampler2DRectShadow sampler, const vec4 coord)
-{
- __asm vec4_tex_rect_proj_shadow __retVal, sampler, coord;
-}
-
-
-
-//// GL_EXT_texture_array
-vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord)
-{
- __asm vec4_tex_1d_array __retVal, sampler, coord;
-}
-
-vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord)
-{
- __asm vec4_tex_2d_array __retVal, sampler, coord;
-}
-
-
-//
-// 8.9 Noise Functions
-//
-// AUTHOR: Stefan Gustavson ([email protected]), Nov 26, 2005
-//
-
-float noise1(const float x)
-{
- __asm float_noise1 __retVal, x;
-}
-
-
-float noise1(const vec2 x)
-{
- __asm float_noise2 __retVal, x;
-}
-
-float noise1(const vec3 x)
-{
- __asm float_noise3 __retVal, x;
-}
-
-float noise1(const vec4 x)
-{
- __asm float_noise4 __retVal, x;
-}
-
-vec2 noise2(const float x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + 19.34);
-}
-
-vec2 noise2(const vec2 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec2(19.34, 7.66));
-}
-
-vec2 noise2(const vec3 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
-}
-
-vec2 noise2(const vec4 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
-}
-
-vec3 noise3(const float x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + 19.34);
- __retVal.z = noise1(x + 5.47);
-}
-
-vec3 noise3(const vec2 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec2(19.34, 7.66));
- __retVal.z = noise1(x + vec2(5.47, 17.85));
-}
-
-vec3 noise3(const vec3 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
- __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04));
-}
-
-vec3 noise3(const vec4 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
- __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19));
-}
-
-vec4 noise4(const float x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + 19.34);
- __retVal.z = noise1(x + 5.47);
- __retVal.w = noise1(x + 23.54);
-}
-
-vec4 noise4(const vec2 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec2 (19.34, 7.66));
- __retVal.z = noise1(x + vec2 (5.47, 17.85));
- __retVal.w = noise1(x + vec2 (23.54, 29.11));
-}
-
-vec4 noise4(const vec3 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
- __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04));
- __retVal.w = noise1(x + vec3(23.54, 29.11, 31.91));
-}
-
-vec4 noise4(const vec4 x)
-{
- __retVal.x = noise1(x);
- __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
- __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19));
- __retVal.w = noise1(x + vec4(23.54, 29.11, 31.91, 37.48));
-}
diff --git a/src/mesa/slang/library/slang_core.gc b/src/mesa/slang/library/slang_core.gc
deleted file mode 100644
index 0a0d15903bc..00000000000
--- a/src/mesa/slang/library/slang_core.gc
+++ /dev/null
@@ -1,2619 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 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.
- */
-
-//
-// This file defines nearly all constructors and operators for built-in data
-// types, using extended language syntax. In general, compiler treats
-// constructors and operators as ordinary functions with some exceptions.
-// For example, the language does not allow functions to be called in
-// constant expressions - here the exception is made to allow it.
-//
-// Each implementation provides its own version of this file. Each
-// implementation can define the required set of operators and constructors
-// in its own fashion.
-//
-// The extended language syntax is only present when compiling this file.
-// It is implicitly included at the very beginning of the compiled shader,
-// so no built-in functions can be used.
-//
-// To communicate with the implementation, a special extended "__asm" keyword
-// is used, followed by an instruction name (any valid identifier), a
-// destination variable identifier and a list of zero or more source
-// variable identifiers.
-//
-// A variable identifier is a variable name declared earlier in the code
-// (as a function parameter, local or global variable).
-//
-// An instruction name designates an instruction that must be exported
-// by the implementation. Each instruction receives data from source
-// variable identifiers and returns data in the destination variable
-// identifier.
-//
-// It is up to the implementation how to define a particular operator
-// or constructor. If it is expected to being used rarely, it can be
-// defined in terms of other operators and constructors,
-// for example:
-//
-// ivec2 __operator + (const ivec2 x, const ivec2 y) {
-// return ivec2 (x[0] + y[0], x[1] + y[1]);
-// }
-//
-// If a particular operator or constructor is expected to be used very
-// often or is an atomic operation (that is, an operation that cannot be
-// expressed in terms of other operations or would create a dependency
-// cycle) it must be defined using one or more __asm constructs.
-//
-// Each implementation must define constructors for all scalar types
-// (bool, float, int). There are 9 scalar-to-scalar constructors
-// (including identity constructors). However, since the language
-// introduces special constructors (like matrix constructor with a single
-// scalar value), implementations must also implement these cases.
-// The compiler provides the following algorithm when resolving a constructor:
-// - try to find a constructor with a prototype matching ours,
-// - if no constructor is found and this is a scalar-to-scalar constructor,
-// raise an error,
-// - if a constructor is found, execute it and return,
-// - count the size of the constructor parameter list - if it is less than
-// the size of our constructor's type, raise an error,
-// - for each parameter in the list do a recursive constructor matching for
-// appropriate scalar fields in the constructed variable,
-//
-// Each implementation must also define a set of operators that deal with
-// built-in data types.
-// There are four kinds of operators:
-// 1) Operators that are implemented only by the compiler: "()" (function
-// call), "," (sequence) and "?:" (selection).
-// 2) Operators that are implemented by the compiler by expressing it in
-// terms of other operators:
-// - "." (field selection) - translated to subscript access,
-// - "&&" (logical and) - translated to "<left_expr> ? <right_expr> :
-// false",
-// - "||" (logical or) - translated to "<left_expr> ? true : <right_expr>",
-// 3) Operators that can be defined by the implementation and if the required
-// prototype is not found, standard behaviour is used:
-// - "==", "!=", "=" (equality, assignment) - compare or assign
-// matching fields one-by-one;
-// note that at least operators for scalar data types must be defined
-// by the implementation to get it work,
-// 4) All other operators not mentioned above. If no required prototype is
-// found, an error is raised. An implementation must follow the language
-// specification to provide all valid operator prototypes.
-//
-
-
-
-//// Basic, scalar constructors/casts
-
-int __constructor(const float f)
-{
- __asm vec4_to_ivec4 __retVal, f;
-}
-
-int __constructor(const bool b)
-{
- __retVal = b;
-}
-
-int __constructor(const int i)
-{
- __retVal = i;
-}
-
-bool __constructor(const int i)
-{
- __asm vec4_sne __retVal, i, 0.0;
-}
-
-bool __constructor(const float f)
-{
- __asm vec4_sne __retVal, f, 0.0;
-}
-
-bool __constructor(const bool b)
-{
- __retVal = b;
-}
-
-float __constructor(const int i)
-{
- __asm ivec4_to_vec4 __retVal, i;
-}
-
-float __constructor(const bool b)
-{
- __asm ivec4_to_vec4 __retVal, b;
-}
-
-float __constructor(const float f)
-{
- __retVal = f;
-}
-
-
-//// vec2 constructors
-
-vec2 __constructor(const float x, const float y)
-{
- __retVal.x = x;
- __retVal.y = y;
-}
-
-vec2 __constructor(const float f)
-{
- __asm vec4_move __retVal.xy, f;
-}
-
-vec2 __constructor(const int i)
-{
- __asm ivec4_to_vec4 __retVal.xy, i;
-}
-
-vec2 __constructor(const bool b)
-{
- __asm ivec4_to_vec4 __retVal.xy, b;
-}
-
-vec2 __constructor(const bvec2 b)
-{
-// __retVal = b;
- __asm ivec4_to_vec4 __retVal.xy, b;
-}
-
-vec2 __constructor(const vec3 v)
-{
- __asm vec4_move __retVal.xy, v.xy;
-}
-
-vec2 __constructor(const vec4 v)
-{
- __asm vec4_move __retVal.xy, v.xy;
-}
-
-
-//// vec3 constructors
-
-vec3 __constructor(const float x, const float y, const float z)
-{
- __retVal.x = x;
- __retVal.y = y;
- __retVal.z = z;
-}
-
-vec3 __constructor(const float f)
-{
- // Note: this could be "__retVal.xyz = f" but that's an illegal assignment
- __asm vec4_move __retVal.xyz, f;
-}
-
-vec3 __constructor(const int i)
-{
- __asm ivec4_to_vec4 __retVal.xyz, i;
-}
-
-vec3 __constructor(const bool b)
-{
- __asm ivec4_to_vec4 __retVal.xyz, b;
-}
-
-vec3 __constructor(const bvec3 b)
-{
- __asm ivec4_to_vec4 __retVal.xyz, b;
-}
-
-vec3 __constructor(const vec4 v)
-{
- __asm vec4_move __retVal.xyz, v;
-}
-
-
-//// vec4 constructors
-
-vec4 __constructor(const float x, const float y, const float z, const float w)
-{
- __retVal.x = x;
- __retVal.y = y;
- __retVal.z = z;
- __retVal.w = w;
-}
-
-vec4 __constructor(const float f)
-{
- // Note: this could be "__retVal = f" but that's an illegal assignment
- __asm vec4_move __retVal, f;
-}
-
-vec4 __constructor(const int i)
-{
- __asm ivec4_to_vec4 __retVal, i;
-}
-
-vec4 __constructor(const bool b)
-{
- __asm ivec4_to_vec4 __retVal, b;
-}
-
-vec4 __constructor(const bvec4 b)
-{
- __asm ivec4_to_vec4 __retVal, b;
-}
-
-vec4 __constructor(const ivec4 i)
-{
- __asm ivec4_to_vec4 __retVal, i;
-}
-
-vec4 __constructor(const vec3 v3, const float f)
-{
- // XXX this constructor shouldn't be needed anymore
- __retVal.xyz = v3;
- __retVal.w = f;
-}
-
-vec4 __constructor(const vec2 v2, const float f1, const float f2)
-{
- // XXX this constructor shouldn't be needed anymore
- __retVal.xy = v2;
- __retVal.z = f1;
- __retVal.w = f2;
-}
-
-
-//// ivec2 constructors
-
-ivec2 __constructor(const int i, const int j)
-{
- __retVal.x = i;
- __retVal.y = j;
-}
-
-ivec2 __constructor(const int i)
-{
- __asm vec4_move __retVal.xy, i;
-}
-
-ivec2 __constructor(const float f)
-{
- __asm vec4_to_ivec4 __retVal.xy, f;
-}
-
-ivec2 __constructor(const bool b)
-{
- __asm vec4_to_ivec4 __retVal.xy, b;
-}
-
-
-//// ivec3 constructors
-
-ivec3 __constructor(const int i, const int j, const int k)
-{
- __retVal.x = i;
- __retVal.y = j;
- __retVal.z = k;
-}
-
-ivec3 __constructor(const int i)
-{
- __asm vec4_move __retVal.xyz, i;
-}
-
-ivec3 __constructor(const float f)
-{
- __asm vec4_to_ivec4 __retVal.xyz, f;
-}
-
-ivec3 __constructor(const bool b)
-{
- __asm vec4_move __retVal.xyz, b;
-}
-
-
-//// ivec4 constructors
-
-ivec4 __constructor(const int x, const int y, const int z, const int w)
-{
- __retVal.x = x;
- __retVal.y = y;
- __retVal.z = z;
- __retVal.w = w;
-}
-
-ivec4 __constructor(const int i)
-{
- __asm vec4_move __retVal, i;
-}
-
-ivec4 __constructor(const float f)
-{
- __asm vec4_to_ivec4 __retVal, f;
-}
-
-ivec4 __constructor(const bool b)
-{
- __asm vec4_to_ivec4 __retVal, b;
-}
-
-
-//// bvec2 constructors
-
-bvec2 __constructor(const bool b1, const bool b2)
-{
- __retVal.x = b1;
- __retVal.y = b2;
-}
-
-bvec2 __constructor(const int i1, const int i2)
-{
- __asm vec4_sne __retVal.x, i1, 0.0;
- __asm vec4_sne __retVal.y, i2, 0.0;
-}
-
-
-bvec2 __constructor(const bool b)
-{
- __asm vec4_move __retVal.xy, b;
-}
-
-bvec2 __constructor(const float f)
-{
- __asm vec4_sne __retVal.xy, f, 0.0;
-}
-
-bvec2 __constructor(const int i)
-{
- __asm vec4_sne __retVal.xy, i, 0.0;
-}
-
-bvec2 __constructor(const vec2 v)
-{
- __asm vec4_sne __retVal.xy, v, 0.0;
-}
-
-bvec2 __constructor(const ivec2 v)
-{
- __asm vec4_sne __retVal.xy, v, 0.0;
-}
-
-
-
-//// bvec3 constructors
-
-bvec3 __constructor(const bool b1, const bool b2, const bool b3)
-{
- __retVal.x = b1;
- __retVal.y = b2;
- __retVal.z = b3;
-}
-
-bvec3 __constructor(const float f1, const float f2, const float f3)
-{
- __asm vec4_sne __retVal.x, f1, 0.0;
- __asm vec4_sne __retVal.y, f2, 0.0;
- __asm vec4_sne __retVal.z, f3, 0.0;
-}
-
-bvec3 __constructor(const bool b)
-{
- __asm vec4_move __retVal.xyz, b;
-}
-
-bvec3 __constructor(const float f)
-{
- __asm vec4_sne __retVal.xyz, f, 0.0;
-}
-
-bvec3 __constructor(const int i)
-{
- __asm vec4_sne __retVal.xyz, i, 0.0;
-}
-
-bvec3 __constructor(const vec3 v)
-{
- __asm vec4_sne __retVal.xyz, v, 0.0;
-}
-
-bvec3 __constructor(const ivec3 v)
-{
- __asm vec4_sne __retVal.xyz, v, 0.0;
-}
-
-
-
-//// bvec4 constructors
-
-bvec4 __constructor(const bool b1, const bool b2, const bool b3, const bool b4)
-{
- __retVal.x = b1;
- __retVal.y = b2;
- __retVal.z = b3;
- __retVal.w = b4;
-}
-
-bvec4 __constructor(const float f1, const float f2, const float f3, const float f4)
-{
- const float zero = 0.0;
- __asm vec4_sne __retVal.x, f1, zero;
- __asm vec4_sne __retVal.y, f2, zero;
- __asm vec4_sne __retVal.z, f3, zero;
- __asm vec4_sne __retVal.w, f4, zero;
-}
-
-bvec4 __constructor(const bool b)
-{
- __asm vec4_move __retVal.xyzw, b;
-}
-
-bvec4 __constructor(const float f)
-{
- __asm vec4_sne __retVal.xyzw, f, 0.0;
-}
-
-bvec4 __constructor(const int i)
-{
- __asm vec4_sne __retVal.xyzw, i, 0.0;
-}
-
-bvec4 __constructor(const vec4 v)
-{
- __asm vec4_sne __retVal.xyzw, v, 0.0;
-}
-
-bvec4 __constructor(const ivec4 v)
-{
- __asm vec4_sne __retVal.xyzw, v, 0.0;
-}
-
-
-
-//// mat2 constructors
-
-mat2 __constructor(const float m00, const float m10,
- const float m01, const float m11)
-{
- __retVal[0].x = m00;
- __retVal[0].y = m10;
- __retVal[1].x = m01;
- __retVal[1].y = m11;
-}
-
-mat2 __constructor(const float f)
-{
- __retVal[0].x = f;
- __retVal[0].y = 0.0;
- __retVal[1].x = 0.0;
- __retVal[1].y = f;
-}
-
-mat2 __constructor(const int i)
-{
- return mat2(float(i));
-}
-
-mat2 __constructor(const bool b)
-{
- return mat2(float(b));
-}
-
-mat2 __constructor(const vec2 c0, const vec2 c1)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
-}
-
-
-//// mat3 constructors
-
-mat3 __constructor(const float m00, const float m10, const float m20,
- const float m01, const float m11, const float m21,
- const float m02, const float m12, const float m22)
-{
- __retVal[0].x = m00;
- __retVal[0].y = m10;
- __retVal[0].z = m20;
- __retVal[1].x = m01;
- __retVal[1].y = m11;
- __retVal[1].z = m21;
- __retVal[2].x = m02;
- __retVal[2].y = m12;
- __retVal[2].z = m22;
-}
-
-mat3 __constructor(const float f)
-{
- vec2 v = vec2(f, 0.0);
- __retVal[0] = v.xyy;
- __retVal[1] = v.yxy;
- __retVal[2] = v.yyx;
-}
-
-mat3 __constructor(const int i)
-{
- return mat3(float(i));
-}
-
-mat3 __constructor(const bool b)
-{
- return mat3(float(b));
-}
-
-mat3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
- __retVal[2] = c2;
-}
-
-
-//// mat4 constructors
-
-mat4 __constructor(const float m00, const float m10, const float m20, const float m30,
- const float m01, const float m11, const float m21, const float m31,
- const float m02, const float m12, const float m22, const float m32,
- const float m03, const float m13, const float m23, const float m33)
-{
- __retVal[0].x = m00;
- __retVal[0].y = m10;
- __retVal[0].z = m20;
- __retVal[0].w = m30;
- __retVal[1].x = m01;
- __retVal[1].y = m11;
- __retVal[1].z = m21;
- __retVal[1].w = m31;
- __retVal[2].x = m02;
- __retVal[2].y = m12;
- __retVal[2].z = m22;
- __retVal[2].w = m32;
- __retVal[3].x = m03;
- __retVal[3].y = m13;
- __retVal[3].z = m23;
- __retVal[3].w = m33;
-}
-
-
-mat4 __constructor(const float f)
-{
- vec2 v = vec2(f, 0.0);
- __retVal[0] = v.xyyy;
- __retVal[1] = v.yxyy;
- __retVal[2] = v.yyxy;
- __retVal[3] = v.yyyx;
-}
-
-mat4 __constructor(const int i)
-{
- return mat4(float(i));
-}
-
-mat4 __constructor(const bool b)
-{
- return mat4(float(b));
-}
-
-mat4 __constructor(const vec4 c0, const vec4 c1, const vec4 c2, const vec4 c3)
-{
- __retVal[0] = c0;
- __retVal[1] = c1;
- __retVal[2] = c2;
- __retVal[3] = c3;
-}
-
-
-
-//// Basic int operators
-
-int __operator + (const int a, const int b)
-{
- __asm vec4_add __retVal, a, b;
-}
-
-int __operator - (const int a, const int b)
-{
- __asm vec4_subtract __retVal, a, b;
-}
-
-int __operator * (const int a, const int b)
-{
- __asm vec4_multiply __retVal, a, b;
-}
-
-int __operator / (const int a, const int b)
-{
- float bInv, x;
- __asm float_rcp bInv, b;
- __asm vec4_multiply x, a, bInv;
- __asm vec4_to_ivec4 __retVal, x;
-}
-
-
-//// Basic ivec2 operators
-
-ivec2 __operator + (const ivec2 a, const ivec2 b)
-{
- __asm vec4_add __retVal, a, b;
-}
-
-ivec2 __operator - (const ivec2 a, const ivec2 b)
-{
- __asm vec4_subtract __retVal, a, b;
-}
-
-ivec2 __operator * (const ivec2 a, const ivec2 b)
-{
- __asm vec4_multiply __retVal, a, b;
-}
-
-ivec2 __operator / (const ivec2 a, const ivec2 b)
-{
- vec2 bInv, x;
- __asm float_rcp bInv.x, b.x;
- __asm float_rcp bInv.y, b.y;
- __asm vec4_multiply x, a, bInv;
- __asm vec4_to_ivec4 __retVal, x;
-}
-
-
-//// Basic ivec3 operators
-
-ivec3 __operator + (const ivec3 a, const ivec3 b)
-{
- __asm vec4_add __retVal, a, b;
-}
-
-ivec3 __operator - (const ivec3 a, const ivec3 b)
-{
- __asm vec4_subtract __retVal, a, b;
-}
-
-ivec3 __operator * (const ivec3 a, const ivec3 b)
-{
- __asm vec4_multiply __retVal, a, b;
-}
-
-ivec3 __operator / (const ivec3 a, const ivec3 b)
-{
- vec3 bInv, x;
- __asm float_rcp bInv.x, b.x;
- __asm float_rcp bInv.y, b.y;
- __asm float_rcp bInv.z, b.z;
- __asm vec4_multiply x, a, bInv;
- __asm vec4_to_ivec4 __retVal, x;
-}
-
-
-//// Basic ivec4 operators
-
-ivec4 __operator + (const ivec4 a, const ivec4 b)
-{
- __asm vec4_add __retVal, a, b;
-}
-
-ivec4 __operator - (const ivec4 a, const ivec4 b)
-{
- __asm vec4_subtract __retVal, a, b;
-}
-
-ivec4 __operator * (const ivec4 a, const ivec4 b)
-{
- __asm vec4_multiply __retVal, a, b;
-}
-
-ivec4 __operator / (const ivec4 a, const ivec4 b)
-{
- vec4 bInv, x;
- __asm float_rcp bInv.x, b.x;
- __asm float_rcp bInv.y, b.y;
- __asm float_rcp bInv.z, b.z;
- __asm float_rcp bInv.w, b.w;
- __asm vec4_multiply x, a, bInv;
- __asm vec4_to_ivec4 __retVal, x;
-}
-
-
-//// Basic float operators
-
-float __operator + (const float a, const float b)
-{
- __asm vec4_add __retVal, a, b;
-}
-
-float __operator - (const float a, const float b)
-{
- __asm vec4_subtract __retVal, a, b;
-}
-
-float __operator * (const float a, const float b)
-{
- __asm vec4_multiply __retVal, a, b;
-}
-
-float __operator / (const float a, const float b)
-{
- float bInv;
- __asm float_rcp bInv.x, b;
- __asm vec4_multiply __retVal, a, bInv;
-}
-
-
-//// Basic vec2 operators
-
-vec2 __operator + (const vec2 v, const vec2 u)
-{
- __asm vec4_add __retVal.xy, v, u;
-}
-
-vec2 __operator - (const vec2 v, const vec2 u)
-{
- __asm vec4_subtract __retVal.xy, v, u;
-}
-
-vec2 __operator * (const vec2 v, const vec2 u)
-{
- __asm vec4_multiply __retVal.xy, v, u;
-}
-
-vec2 __operator / (const vec2 v, const vec2 u)
-{
- vec2 w; // = 1 / u
- __asm float_rcp w.x, u.x;
- __asm float_rcp w.y, u.y;
- __asm vec4_multiply __retVal.xy, v, w;
-}
-
-
-//// Basic vec3 operators
-
-vec3 __operator + (const vec3 v, const vec3 u)
-{
- __asm vec4_add __retVal.xyz, v, u;
-}
-
-vec3 __operator - (const vec3 v, const vec3 u)
-{
- __asm vec4_subtract __retVal.xyz, v, u;
-}
-
-vec3 __operator * (const vec3 v, const vec3 u)
-{
- __asm vec4_multiply __retVal.xyz, v, u;
-}
-
-vec3 __operator / (const vec3 v, const vec3 u)
-{
- vec3 w; // = 1 / u
- __asm float_rcp w.x, u.x;
- __asm float_rcp w.y, u.y;
- __asm float_rcp w.z, u.z;
- __asm vec4_multiply __retVal.xyz, v, w;
-}
-
-
-//// Basic vec4 operators
-
-vec4 __operator + (const vec4 v, const vec4 u)
-{
- __asm vec4_add __retVal, v, u;
-}
-
-vec4 __operator - (const vec4 v, const vec4 u)
-{
- __asm vec4_subtract __retVal, v, u;
-}
-
-vec4 __operator * (const vec4 v, const vec4 u)
-{
- __asm vec4_multiply __retVal, v, u;
-}
-
-vec4 __operator / (const vec4 v, const vec4 u)
-{
- vec4 w; // = 1 / u
- __asm float_rcp w.x, u.x;
- __asm float_rcp w.y, u.y;
- __asm float_rcp w.z, u.z;
- __asm float_rcp w.w, u.w;
- __asm vec4_multiply __retVal, v, w;
-}
-
-
-
-
-//// Basic vec2/float operators
-
-vec2 __operator + (const float a, const vec2 u)
-{
- __asm vec4_add __retVal.xy, a, u.xy;
-}
-
-vec2 __operator + (const vec2 v, const float b)
-{
- __asm vec4_add __retVal.xy, v.xy, b;
-}
-
-vec2 __operator - (const float a, const vec2 u)
-{
- __asm vec4_subtract __retVal.xy, a, u.xy;
-}
-
-vec2 __operator - (const vec2 v, const float b)
-{
- __asm vec4_subtract __retVal.xy, v.xy, b;
-}
-
-vec2 __operator * (const float a, const vec2 u)
-{
- __asm vec4_multiply __retVal.xy, a, u.xy;
-}
-
-vec2 __operator * (const vec2 v, const float b)
-{
- __asm vec4_multiply __retVal.xy, v.xy, b;
-}
-
-vec2 __operator / (const float a, const vec2 u)
-{
- vec2 invU;
- __asm float_rcp invU.x, u.x;
- __asm float_rcp invU.y, u.y;
- __asm vec4_multiply __retVal.xy, a, invU.xy;
-}
-
-vec2 __operator / (const vec2 v, const float b)
-{
- float invB;
- __asm float_rcp invB, b;
- __asm vec4_multiply __retVal.xy, v.xy, invB;
-}
-
-
-//// Basic vec3/float operators
-
-vec3 __operator + (const float a, const vec3 u)
-{
- __asm vec4_add __retVal.xyz, a, u.xyz;
-}
-
-vec3 __operator + (const vec3 v, const float b)
-{
- __asm vec4_add __retVal.xyz, v.xyz, b;
-}
-
-vec3 __operator - (const float a, const vec3 u)
-{
- __asm vec4_subtract __retVal.xyz, a, u.xyz;
-}
-
-vec3 __operator - (const vec3 v, const float b)
-{
- __asm vec4_subtract __retVal.xyz, v.xyz, b;
-}
-
-vec3 __operator * (const float a, const vec3 u)
-{
- __asm vec4_multiply __retVal.xyz, a, u.xyz;
-}
-
-vec3 __operator * (const vec3 v, const float b)
-{
- __asm vec4_multiply __retVal.xyz, v.xyz, b;
-}
-
-vec3 __operator / (const float a, const vec3 u)
-{
- vec3 invU;
- __asm float_rcp invU.x, u.x;
- __asm float_rcp invU.y, u.y;
- __asm float_rcp invU.z, u.z;
- __asm vec4_multiply __retVal.xyz, a, invU.xyz;
-}
-
-vec3 __operator / (const vec3 v, const float b)
-{
- float invB;
- __asm float_rcp invB, b;
- __asm vec4_multiply __retVal.xyz, v.xyz, invB;
-}
-
-
-//// Basic vec4/float operators
-
-vec4 __operator + (const float a, const vec4 u)
-{
- __asm vec4_add __retVal, a, u;
-}
-
-vec4 __operator + (const vec4 v, const float b)
-{
- __asm vec4_add __retVal, v, b;
-}
-
-vec4 __operator - (const float a, const vec4 u)
-{
- __asm vec4_subtract __retVal, a, u;
-}
-
-vec4 __operator - (const vec4 v, const float b)
-{
- __asm vec4_subtract __retVal, v, b;
-}
-
-vec4 __operator * (const float a, const vec4 u)
-{
- __asm vec4_multiply __retVal, a, u;
-}
-
-vec4 __operator * (const vec4 v, const float b)
-{
- __asm vec4_multiply __retVal, v, b;
-}
-
-vec4 __operator / (const float a, const vec4 u)
-{
- vec4 invU;
- __asm float_rcp invU.x, u.x;
- __asm float_rcp invU.y, u.y;
- __asm float_rcp invU.z, u.z;
- __asm float_rcp invU.w, u.w;
- __asm vec4_multiply __retVal, a, invU;
-}
-
-vec4 __operator / (const vec4 v, const float b)
-{
- float invB;
- __asm float_rcp invB, b;
- __asm vec4_multiply __retVal, v, invB;
-}
-
-
-
-//// Basic ivec2/int operators
-
-ivec2 __operator + (const int a, const ivec2 u)
-{
- __retVal = ivec2(a) + u;
-}
-
-ivec2 __operator + (const ivec2 v, const int b)
-{
- __retVal = v + ivec2(b);
-}
-
-ivec2 __operator - (const int a, const ivec2 u)
-{
- __retVal = ivec2(a) - u;
-}
-
-ivec2 __operator - (const ivec2 v, const int b)
-{
- __retVal = v - ivec2(b);
-}
-
-ivec2 __operator * (const int a, const ivec2 u)
-{
- __retVal = ivec2(a) * u;
-}
-
-ivec2 __operator * (const ivec2 v, const int b)
-{
- __retVal = v * ivec2(b);
-}
-
-ivec2 __operator / (const int a, const ivec2 u)
-{
- __retVal = ivec2(a) / u;
-}
-
-ivec2 __operator / (const ivec2 v, const int b)
-{
- __retVal = v / ivec2(b);
-}
-
-
-//// Basic ivec3/int operators
-
-ivec3 __operator + (const int a, const ivec3 u)
-{
- __retVal = ivec3(a) + u;
-}
-
-ivec3 __operator + (const ivec3 v, const int b)
-{
- __retVal = v + ivec3(b);
-}
-
-ivec3 __operator - (const int a, const ivec3 u)
-{
- __retVal = ivec3(a) - u;
-}
-
-ivec3 __operator - (const ivec3 v, const int b)
-{
- __retVal = v - ivec3(b);
-}
-
-ivec3 __operator * (const int a, const ivec3 u)
-{
- __retVal = ivec3(a) * u;
-}
-
-ivec3 __operator * (const ivec3 v, const int b)
-{
- __retVal = v * ivec3(b);
-}
-
-ivec3 __operator / (const int a, const ivec3 u)
-{
- __retVal = ivec3(a) / u;
-}
-
-ivec3 __operator / (const ivec3 v, const int b)
-{
- __retVal = v / ivec3(b);
-}
-
-
-//// Basic ivec4/int operators
-
-ivec4 __operator + (const int a, const ivec4 u)
-{
- __retVal = ivec4(a) + u;
-}
-
-ivec4 __operator + (const ivec4 v, const int b)
-{
- __retVal = v + ivec4(b);
-}
-
-ivec4 __operator - (const int a, const ivec4 u)
-{
- __retVal = ivec4(a) - u;
-}
-
-ivec4 __operator - (const ivec4 v, const int b)
-{
- __retVal = v - ivec4(b);
-}
-
-ivec4 __operator * (const int a, const ivec4 u)
-{
- __retVal = ivec4(a) * u;
-}
-
-ivec4 __operator * (const ivec4 v, const int b)
-{
- __retVal = v * ivec4(b);
-}
-
-ivec4 __operator / (const int a, const ivec4 u)
-{
- __retVal = ivec4(a) / u;
-}
-
-ivec4 __operator / (const ivec4 v, const int b)
-{
- __retVal = v / ivec4(b);
-}
-
-
-
-
-//// Unary negation operator
-
-int __operator - (const int a)
-{
- __asm vec4_negate __retVal.x, a;
-}
-
-ivec2 __operator - (const ivec2 v)
-{
- __asm vec4_negate __retVal, v;
-}
-
-ivec3 __operator - (const ivec3 v)
-{
- __asm vec4_negate __retVal, v;
-}
-
-ivec4 __operator - (const ivec4 v)
-{
- __asm vec4_negate __retVal, v;
-}
-
-float __operator - (const float a)
-{
- __asm vec4_negate __retVal.x, a;
-}
-
-vec2 __operator - (const vec2 v)
-{
- __asm vec4_negate __retVal.xy, v.xy;
-}
-
-vec3 __operator - (const vec3 v)
-{
- __asm vec4_negate __retVal.xyz, v.xyz;
-}
-
-vec4 __operator - (const vec4 v)
-{
- __asm vec4_negate __retVal, v;
-}
-
-mat2 __operator - (const mat2 m)
-{
- __retVal[0] = -m[0];
- __retVal[1] = -m[1];
-}
-
-mat3 __operator - (const mat3 m)
-{
- __retVal[0] = -m[0];
- __retVal[1] = -m[1];
- __retVal[2] = -m[2];
-}
-
-mat4 __operator - (const mat4 m)
-{
- __retVal[0] = -m[0];
- __retVal[1] = -m[1];
- __retVal[2] = -m[2];
- __retVal[3] = -m[3];
-}
-
-
-
-//// dot product
-
-float dot(const float a, const float b)
-{
- __retVal = a * b;
-}
-
-float dot(const vec2 a, const vec2 b)
-{
- __retVal = a.x * b.x + a.y * b.y;
-}
-
-float dot(const vec3 a, const vec3 b)
-{
- __asm vec3_dot __retVal, a, b;
-}
-
-float dot(const vec4 a, const vec4 b)
-{
- __asm vec4_dot __retVal, a, b;
-}
-
-
-
-//// int assignment operators
-
-int __operator += (inout int a, const int b)
-{
- a = a + b;
- return a;
-}
-
-int __operator -= (inout int a, const int b)
-{
- a = a - b;
- return a;
-}
-
-int __operator *= (inout int a, const int b)
-{
- a = a * b;
- return a;
-}
-
-int __operator /= (inout int a, const int b)
-{
- a = a / b;
- return a;
-}
-
-
-//// ivec2 assignment operators
-
-ivec2 __operator += (inout ivec2 v, const ivec2 u)
-{
- v = v + u;
- return v;
-}
-
-ivec2 __operator -= (inout ivec2 v, const ivec2 u)
-{
- v = v - u;
- return v;
-}
-
-ivec2 __operator *= (inout ivec2 v, const ivec2 u)
-{
- v = v * u;
- return v;
-}
-
-ivec2 __operator /= (inout ivec2 v, const ivec2 u)
-{
- v = v / u;
- return v;
-}
-
-
-//// ivec3 assignment operators
-
-ivec3 __operator += (inout ivec3 v, const ivec3 u)
-{
- v = v + u;
- return v;
-}
-
-ivec3 __operator -= (inout ivec3 v, const ivec3 u)
-{
- v = v - u;
- return v;
-}
-
-ivec3 __operator *= (inout ivec3 v, const ivec3 u)
-{
- v = v * u;
- return v;
-}
-
-ivec3 __operator /= (inout ivec3 v, const ivec3 u)
-{
- v = v / u;
- return v;
-}
-
-
-//// ivec4 assignment operators
-
-ivec4 __operator += (inout ivec4 v, const ivec4 u)
-{
- v = v + u;
- return v;
-}
-
-ivec4 __operator -= (inout ivec4 v, const ivec4 u)
-{
- v = v - u;
- return v;
-}
-
-ivec4 __operator *= (inout ivec4 v, const ivec4 u)
-{
- v = v * u;
- return v;
-}
-
-ivec4 __operator /= (inout ivec4 v, const ivec4 u)
-{
- v = v / u;
- return v;
-}
-
-
-//// float assignment operators
-
-float __operator += (inout float a, const float b)
-{
- a = a + b;
- return a;
-}
-
-float __operator -= (inout float a, const float b)
-{
- a = a - b;
- return a;
-}
-
-float __operator *= (inout float a, const float b)
-{
- a = a * b;
- return a;
-}
-
-float __operator /= (inout float a, const float b)
-{
- a = a / b;
- return a;
-}
-
-
-//// vec2 assignment operators
-
-vec2 __operator += (inout vec2 v, const vec2 u)
-{
- v = v + u;
- return v;
-}
-
-vec2 __operator -= (inout vec2 v, const vec2 u)
-{
- v = v - u;
- return v;
-}
-
-vec2 __operator *= (inout vec2 v, const vec2 u)
-{
- v = v * u;
- return v;
-}
-
-vec2 __operator /= (inout vec2 v, const vec2 u)
-{
- v = v / u;
- return v;
-}
-
-
-//// vec3 assignment operators
-
-vec3 __operator += (inout vec3 v, const vec3 u)
-{
- v = v + u;
- return v;
-}
-
-vec3 __operator -= (inout vec3 v, const vec3 u)
-{
- v = v - u;
- return v;
-}
-
-vec3 __operator *= (inout vec3 v, const vec3 u)
-{
- v = v * u;
- return v;
-}
-
-vec3 __operator /= (inout vec3 v, const vec3 u)
-{
- v = v / u;
- return v;
-}
-
-
-//// vec4 assignment operators
-
-vec4 __operator += (inout vec4 v, const vec4 u)
-{
- v = v + u;
- return v;
-}
-
-vec4 __operator -= (inout vec4 v, const vec4 u)
-{
- v = v - u;
- return v;
-}
-
-vec4 __operator *= (inout vec4 v, const vec4 u)
-{
- v = v * u;
- return v;
-}
-
-vec4 __operator /= (inout vec4 v, const vec4 u)
-{
- v = v / u;
- return v;
-}
-
-
-
-//// ivec2/int assignment operators
-
-ivec2 __operator += (inout ivec2 v, const int a)
-{
- v = v + ivec2(a);
- return v;
-}
-
-ivec2 __operator -= (inout ivec2 v, const int a)
-{
- v = v - ivec2(a);
- return v;
-}
-
-ivec2 __operator *= (inout ivec2 v, const int a)
-{
- v = v * ivec2(a);
- return v;
-}
-
-ivec2 __operator /= (inout ivec2 v, const int a)
-{
- v = v / ivec2(a);
- return v;
-}
-
-
-//// ivec3/int assignment operators
-
-ivec3 __operator += (inout ivec3 v, const int a)
-{
- v = v + ivec3(a);
- return v;
-}
-
-ivec3 __operator -= (inout ivec3 v, const int a)
-{
- v = v - ivec3(a);
- return v;
-}
-
-ivec3 __operator *= (inout ivec3 v, const int a)
-{
- v = v * ivec3(a);
- return v;
-}
-
-ivec4 __operator /= (inout ivec3 v, const int a)
-{
- v = v / ivec3(a);
- return v;
-}
-
-
-//// ivec4/int assignment operators
-
-ivec4 __operator += (inout ivec4 v, const int a)
-{
- v = v + ivec4(a);
- return v;
-}
-
-ivec4 __operator -= (inout ivec4 v, const int a)
-{
- v = v - ivec4(a);
- return v;
-}
-
-ivec4 __operator *= (inout ivec4 v, const int a)
-{
- v = v * ivec4(a);
- return v;
-}
-
-ivec4 __operator /= (inout ivec4 v, const int a)
-{
- v = v / ivec4(a);
- return v;
-}
-
-
-
-//// vec2/float assignment operators
-
-vec2 __operator += (inout vec2 v, const float a)
-{
- v = v + vec2(a);
- return v;
-}
-
-vec2 __operator -= (inout vec2 v, const float a)
-{
- v = v - vec2(a);
- return v;
-}
-
-vec2 __operator *= (inout vec2 v, const float a)
-{
- v = v * vec2(a);
- return v;
-}
-
-vec2 __operator /= (inout vec2 v, const float a)
-{
- v = v / vec2(a);
- return v;
-}
-
-
-//// vec3/float assignment operators
-
-vec3 __operator += (inout vec3 v, const float a)
-{
- v = v + vec3(a);
- return v;
-}
-
-vec3 __operator -= (inout vec3 v, const float a)
-{
- v = v - vec3(a);
- return v;
-}
-
-vec3 __operator *= (inout vec3 v, const float a)
-{
- v = v * vec3(a);
- return v;
-}
-
-vec3 __operator /= (inout vec3 v, const float a)
-{
- v = v / vec3(a);
- return v;
-}
-
-
-//// vec4/float assignment operators
-
-vec4 __operator += (inout vec4 v, const float a)
-{
- v = v + vec4(a);
- return v;
-}
-
-vec4 __operator -= (inout vec4 v, const float a)
-{
- v = v - vec4(a);
- return v;
-}
-
-vec4 __operator *= (inout vec4 v, const float a)
-{
- v = v * vec4(a);
- return v;
-}
-
-vec4 __operator /= (inout vec4 v, const float a)
-{
- v = v / vec4(a);
- return v;
-}
-
-
-
-
-
-//// Basic mat2 operations
-
-mat2 __operator + (const mat2 m, const mat2 n)
-{
- __retVal[0] = m[0] + n[0];
- __retVal[1] = m[1] + n[1];
-}
-
-mat2 __operator - (const mat2 m, const mat2 n)
-{
- __retVal[0] = m[0] - n[0];
- __retVal[1] = m[1] - n[1];
-}
-
-mat2 __operator * (const mat2 m, const mat2 n)
-{
- __retVal[0] = m[0] * n[0].xx + m[1] * n[0].yy;
- __retVal[1] = m[0] * n[1].xx + m[1] * n[1].yy;
-}
-
-mat2 __operator / (const mat2 m, const mat2 n)
-{
- __retVal[0] = m[0] / n[0];
- __retVal[1] = m[1] / n[1];
-}
-
-
-//// Basic mat3 operations
-
-mat3 __operator + (const mat3 m, const mat3 n)
-{
- __retVal[0] = m[0] + n[0];
- __retVal[1] = m[1] + n[1];
- __retVal[2] = m[2] + n[2];
-}
-
-mat3 __operator - (const mat3 m, const mat3 n)
-{
- __retVal[0] = m[0] - n[0];
- __retVal[1] = m[1] - n[1];
- __retVal[2] = m[2] - n[2];
-}
-
-mat3 __operator * (const mat3 m, const mat3 n)
-{
- __retVal[0] = m[0] * n[0].xxx + m[1] * n[0].yyy + m[2] * n[0].zzz;
- __retVal[1] = m[0] * n[1].xxx + m[1] * n[1].yyy + m[2] * n[1].zzz;
- __retVal[2] = m[0] * n[2].xxx + m[1] * n[2].yyy + m[2] * n[2].zzz;
-}
-
-mat3 __operator / (const mat3 m, const mat3 n)
-{
- __retVal[0] = m[0] / n[0];
- __retVal[1] = m[1] / n[1];
- __retVal[2] = m[2] / n[2];
-}
-
-
-//// Basic mat4 operations
-
-mat4 __operator + (const mat4 m, const mat4 n)
-{
- __retVal[0] = m[0] + n[0];
- __retVal[1] = m[1] + n[1];
- __retVal[2] = m[2] + n[2];
- __retVal[3] = m[3] + n[3];
-}
-
-mat4 __operator - (const mat4 m, const mat4 n)
-{
- __retVal[0] = m[0] - n[0];
- __retVal[1] = m[1] - n[1];
- __retVal[2] = m[2] - n[2];
- __retVal[3] = m[3] - n[3];
-}
-
-mat4 __operator * (const mat4 m, const mat4 n)
-{
- __retVal[0] = m[0] * n[0].xxxx + m[1] * n[0].yyyy + m[2] * n[0].zzzz + m[3] * n[0].wwww;
- __retVal[1] = m[0] * n[1].xxxx + m[1] * n[1].yyyy + m[2] * n[1].zzzz + m[3] * n[1].wwww;
- __retVal[2] = m[0] * n[2].xxxx + m[1] * n[2].yyyy + m[2] * n[2].zzzz + m[3] * n[2].wwww;
- __retVal[3] = m[0] * n[3].xxxx + m[1] * n[3].yyyy + m[2] * n[3].zzzz + m[3] * n[3].wwww;
-}
-
-mat4 __operator / (const mat4 m, const mat4 n)
-{
- __retVal[0] = m[0] / n[0];
- __retVal[1] = m[1] / n[1];
- __retVal[2] = m[2] / n[2];
- __retVal[3] = m[3] / n[3];
-}
-
-
-//// mat2/float operations
-
-mat2 __operator + (const float a, const mat2 n)
-{
- __retVal[0] = a + n[0];
- __retVal[1] = a + n[1];
-}
-
-mat2 __operator + (const mat2 m, const float b)
-{
- __retVal[0] = m[0] + b;
- __retVal[1] = m[1] + b;
-}
-
-mat2 __operator - (const float a, const mat2 n)
-{
- __retVal[0] = a - n[0];
- __retVal[1] = a - n[1];
-}
-
-mat2 __operator - (const mat2 m, const float b)
-{
- __retVal[0] = m[0] - b;
- __retVal[1] = m[1] - b;
-}
-
-mat2 __operator * (const float a, const mat2 n)
-{
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
-}
-
-mat2 __operator * (const mat2 m, const float b)
-{
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
-}
-
-mat2 __operator / (const float a, const mat2 n)
-{
- __retVal[0] = a / n[0];
- __retVal[1] = a / n[1];
-}
-
-mat2 __operator / (const mat2 m, const float b)
-{
- __retVal[0] = m[0] / b;
- __retVal[1] = m[1] / b;
-}
-
-
-//// mat3/float operations
-
-mat3 __operator + (const float a, const mat3 n)
-{
- __retVal[0] = a + n[0];
- __retVal[1] = a + n[1];
- __retVal[2] = a + n[2];
-}
-
-mat3 __operator + (const mat3 m, const float b)
-{
- __retVal[0] = m[0] + b;
- __retVal[1] = m[1] + b;
- __retVal[2] = m[2] + b;
-}
-
-mat3 __operator - (const float a, const mat3 n)
-{
- __retVal[0] = a - n[0];
- __retVal[1] = a - n[1];
- __retVal[2] = a - n[2];
-}
-
-mat3 __operator - (const mat3 m, const float b)
-{
- __retVal[0] = m[0] - b;
- __retVal[1] = m[1] - b;
- __retVal[2] = m[2] - b;
-}
-
-mat3 __operator * (const float a, const mat3 n)
-{
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
- __retVal[2] = a * n[2];
-}
-
-mat3 __operator * (const mat3 m, const float b)
-{
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
- __retVal[2] = m[2] * b;
-}
-
-mat3 __operator / (const float a, const mat3 n)
-{
- __retVal[0] = a / n[0];
- __retVal[1] = a / n[1];
- __retVal[2] = a / n[2];
-}
-
-mat3 __operator / (const mat3 m, const float b)
-{
- __retVal[0] = m[0] / b;
- __retVal[1] = m[1] / b;
- __retVal[2] = m[2] / b;
-}
-
-
-//// mat4/float operations
-
-mat4 __operator + (const float a, const mat4 n)
-{
- __retVal[0] = a + n[0];
- __retVal[1] = a + n[1];
- __retVal[2] = a + n[2];
- __retVal[3] = a + n[3];
-}
-
-mat4 __operator + (const mat4 m, const float b)
-{
- __retVal[0] = m[0] + b;
- __retVal[1] = m[1] + b;
- __retVal[2] = m[2] + b;
- __retVal[3] = m[3] + b;
-}
-
-mat4 __operator - (const float a, const mat4 n)
-{
- __retVal[0] = a - n[0];
- __retVal[1] = a - n[1];
- __retVal[2] = a - n[2];
- __retVal[3] = a - n[3];
-}
-
-mat4 __operator - (const mat4 m, const float b)
-{
- __retVal[0] = m[0] - b;
- __retVal[1] = m[1] - b;
- __retVal[2] = m[2] - b;
- __retVal[3] = m[3] - b;
-}
-
-mat4 __operator * (const float a, const mat4 n)
-{
- __retVal[0] = a * n[0];
- __retVal[1] = a * n[1];
- __retVal[2] = a * n[2];
- __retVal[3] = a * n[3];
-}
-
-mat4 __operator * (const mat4 m, const float b)
-{
- __retVal[0] = m[0] * b;
- __retVal[1] = m[1] * b;
- __retVal[2] = m[2] * b;
- __retVal[3] = m[3] * b;
-}
-
-mat4 __operator / (const float a, const mat4 n)
-{
- __retVal[0] = a / n[0];
- __retVal[1] = a / n[1];
- __retVal[2] = a / n[2];
- __retVal[3] = a / n[3];
-}
-
-mat4 __operator / (const mat4 m, const float b)
-{
- __retVal[0] = m[0] / b;
- __retVal[1] = m[1] / b;
- __retVal[2] = m[2] / b;
- __retVal[3] = m[3] / b;
-}
-
-
-
-//// matrix / vector products
-
-vec2 __operator * (const mat2 m, const vec2 v)
-{
- __retVal = m[0] * v.xx
- + m[1] * v.yy;
-}
-
-vec2 __operator * (const vec2 v, const mat2 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
-}
-
-vec3 __operator * (const mat3 m, const vec3 v)
-{
- __retVal = m[0] * v.xxx
- + m[1] * v.yyy
- + m[2] * v.zzz;
-}
-
-vec3 __operator * (const vec3 v, const mat3 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
- __retVal.z = dot(v, m[2]);
-}
-
-vec4 __operator * (const mat4 m, const vec4 v)
-{
- __retVal = m[0] * v.xxxx
- + m[1] * v.yyyy
- + m[2] * v.zzzz
- + m[3] * v.wwww;
-}
-
-vec4 __operator * (const vec4 v, const mat4 m)
-{
- __retVal.x = dot(v, m[0]);
- __retVal.y = dot(v, m[1]);
- __retVal.z = dot(v, m[2]);
- __retVal.w = dot(v, m[3]);
-}
-
-
-
-//// mat2 assignment operators
-
-mat2 __operator += (inout mat2 m, const mat2 n)
-{
- m[0] = m[0] + n[0];
- m[1] = m[1] + n[1];
- return m;
-}
-
-mat2 __operator -= (inout mat2 m, const mat2 n)
-{
- m[0] = m[0] - n[0];
- m[1] = m[1] - n[1];
- return m;
-}
-
-mat2 __operator *= (inout mat2 m, const mat2 n)
-{
- m = m * n;
- return m;
-}
-
-mat2 __operator /= (inout mat2 m, const mat2 n)
-{
- m[0] = m[0] / n[0];
- m[1] = m[1] / n[1];
- return m;
-}
-
-
-//// mat3 assignment operators
-
-mat3 __operator += (inout mat3 m, const mat3 n)
-{
- m[0] = m[0] + n[0];
- m[1] = m[1] + n[1];
- m[2] = m[2] + n[2];
- return m;
-}
-
-mat3 __operator -= (inout mat3 m, const mat3 n)
-{
- m[0] = m[0] - n[0];
- m[1] = m[1] - n[1];
- m[2] = m[2] - n[2];
- return m;
-}
-
-mat3 __operator *= (inout mat3 m, const mat3 n)
-{
- m = m * n;
- return m;
-}
-
-mat3 __operator /= (inout mat3 m, const mat3 n)
-{
- m[0] = m[0] / n[0];
- m[1] = m[1] / n[1];
- m[2] = m[2] / n[2];
- return m;
-}
-
-
-// mat4 assignment operators
-
-mat4 __operator += (inout mat4 m, const mat4 n)
-{
- m[0] = m[0] + n[0];
- m[1] = m[1] + n[1];
- m[2] = m[2] + n[2];
- m[3] = m[3] + n[3];
- return m;
-}
-
-mat4 __operator -= (inout mat4 m, const mat4 n)
-{
- m[0] = m[0] - n[0];
- m[1] = m[1] - n[1];
- m[2] = m[2] - n[2];
- m[3] = m[3] - n[3];
- return m;
-}
-
-mat4 __operator *= (inout mat4 m, const mat4 n)
-{
- m = m * n;
- return m;
-}
-
-mat4 __operator /= (inout mat4 m, const mat4 n)
-{
- m[0] = m[0] / n[0];
- m[1] = m[1] / n[1];
- m[2] = m[2] / n[2];
- m[3] = m[3] / n[3];
- return m;
-}
-
-
-//// mat2/float assignment operators
-
-mat2 __operator += (inout mat2 m, const float a)
-{
- vec2 v = vec2(a);
- m[0] = m[0] + v;
- m[1] = m[1] + v;
- return m;
-}
-
-mat2 __operator -= (inout mat2 m, const float a)
-{
- vec2 v = vec2(a);
- m[0] = m[0] - v;
- m[1] = m[1] - v;
- return m;
-}
-
-mat2 __operator *= (inout mat2 m, const float a)
-{
- vec2 v = vec2(a);
- m[0] = m[0] * v;
- m[1] = m[1] * v;
- return m;
-}
-
-mat2 __operator /= (inout mat2 m, const float a)
-{
- vec2 v = vec2(1.0 / a);
- m[0] = m[0] * v;
- m[1] = m[1] * v;
- return m;
-}
-
-
-//// mat3/float assignment operators
-
-mat3 __operator += (inout mat3 m, const float a)
-{
- vec3 v = vec3(a);
- m[0] = m[0] + v;
- m[1] = m[1] + v;
- m[2] = m[2] + v;
- return m;
-}
-
-mat3 __operator -= (inout mat3 m, const float a)
-{
- vec3 v = vec3(a);
- m[0] = m[0] - v;
- m[1] = m[1] - v;
- m[2] = m[2] - v;
- return m;
-}
-
-mat3 __operator *= (inout mat3 m, const float a)
-{
- vec3 v = vec3(a);
- m[0] = m[0] * v;
- m[1] = m[1] * v;
- m[2] = m[2] * v;
- return m;
-}
-
-mat3 __operator /= (inout mat3 m, const float a)
-{
- vec3 v = vec3(1.0 / a);
- m[0] = m[0] * v;
- m[1] = m[1] * v;
- m[2] = m[2] * v;
- return m;
-}
-
-
-//// mat4/float assignment operators
-
-mat4 __operator += (inout mat4 m, const float a)
-{
- vec4 v = vec4(a);
- m[0] = m[0] + v;
- m[1] = m[1] + v;
- m[2] = m[2] + v;
- m[3] = m[3] + v;
- return m;
-}
-
-mat4 __operator -= (inout mat4 m, const float a)
-{
- vec4 v = vec4(a);
- m[0] = m[0] - v;
- m[1] = m[1] - v;
- m[2] = m[2] - v;
- m[3] = m[3] - v;
- return m;
-}
-
-mat4 __operator *= (inout mat4 m, const float a)
-{
- vec4 v = vec4(a);
- m[0] = m[0] * v;
- m[1] = m[1] * v;
- m[2] = m[2] * v;
- m[3] = m[3] * v;
- return m;
-}
-
-mat4 __operator /= (inout mat4 m, const float a)
-{
- vec4 v = vec4(1.0 / a);
- m[0] = m[0] * v;
- m[1] = m[1] * v;
- m[2] = m[2] * v;
- m[3] = m[3] * v;
- return m;
-}
-
-
-
-//// vec/mat assignment operators
-
-vec2 __operator *= (inout vec2 v, const mat2 m)
-{
- v = v * m;
- return v;
-}
-
-vec3 __operator *= (inout vec3 v, const mat3 m)
-{
- v = v * m;
- return v;
-}
-
-vec4 __operator *= (inout vec4 v, const mat4 m)
-{
- v = v * m;
- return v;
-}
-
-
-
-//// pre-decrement operators
-
-int __operator --(inout int a)
-{
- a = a - 1;
- __retVal = a;
-}
-
-ivec2 __operator --(inout ivec2 v)
-{
- v = v - ivec2(1);
- __retVal = v;
-}
-
-ivec3 __operator --(inout ivec3 v)
-{
- v = v - ivec3(1);
- __retVal = v;
-}
-
-ivec4 __operator --(inout ivec4 v)
-{
- v = v - ivec4(1);
- __retVal = v;
-}
-
-
-float __operator --(inout float a)
-{
- a = a - 1.0;
- __retVal = a;
-}
-
-vec2 __operator --(inout vec2 v)
-{
- v = v - vec2(1.0);
- __retVal = v;
-}
-
-vec3 __operator --(inout vec3 v)
-{
- v = v - vec3(1.0);
- __retVal = v;
-}
-
-vec4 __operator --(inout vec4 v)
-{
- v = v - vec4(1.0);
- __retVal = v;
-}
-
-
-mat2 __operator --(inout mat2 m)
-{
- m[0] = m[0] - vec2(1.0);
- m[1] = m[1] - vec2(1.0);
- __retVal = m;
-}
-
-mat3 __operator --(inout mat3 m)
-{
- m[0] = m[0] - vec3(1.0);
- m[1] = m[1] - vec3(1.0);
- m[2] = m[2] - vec3(1.0);
- __retVal = m;
-}
-
-mat4 __operator --(inout mat4 m)
-{
- m[0] = m[0] - vec4(1.0);
- m[1] = m[1] - vec4(1.0);
- m[2] = m[2] - vec4(1.0);
- m[3] = m[3] - vec4(1.0);
- __retVal = m;
-}
-
-
-//// pre-increment operators
-
-int __operator ++(inout int a)
-{
- a = a + 1;
- __retVal = a;
-}
-
-ivec2 __operator ++(inout ivec2 v)
-{
- v = v + ivec2(1);
- __retVal = v;
-}
-
-ivec3 __operator ++(inout ivec3 v)
-{
- v = v + ivec3(1);
- __retVal = v;
-}
-
-ivec4 __operator ++(inout ivec4 v)
-{
- v = v + ivec4(1);
- __retVal = v;
-}
-
-
-float __operator ++(inout float a)
-{
- a = a + 1.0;
- __retVal = a;
-}
-
-vec2 __operator ++(inout vec2 v)
-{
- v = v + vec2(1.0);
- __retVal = v;
-}
-
-vec3 __operator ++(inout vec3 v)
-{
- v = v + vec3(1.0);
- __retVal = v;
-}
-
-vec4 __operator ++(inout vec4 v)
-{
- v = v + vec4(1.0);
- __retVal = v;
-}
-
-
-mat2 __operator ++(inout mat2 m)
-{
- m[0] = m[0] + vec2(1.0);
- m[1] = m[1] + vec2(1.0);
- __retVal = m;
-}
-
-mat3 __operator ++(inout mat3 m)
-{
- m[0] = m[0] + vec3(1.0);
- m[1] = m[1] + vec3(1.0);
- m[2] = m[2] + vec3(1.0);
- __retVal = m;
-}
-
-mat4 __operator ++(inout mat4 m)
-{
- m[0] = m[0] + vec4(1.0);
- m[1] = m[1] + vec4(1.0);
- m[2] = m[2] + vec4(1.0);
- m[3] = m[3] + vec4(1.0);
- __retVal = m;
-}
-
-
-
-//// post-decrement
-
-int __postDecr(inout int a)
-{
- __retVal = a;
- a = a - 1;
-}
-
-ivec2 __postDecr(inout ivec2 v)
-{
- __retVal = v;
- v = v - ivec2(1);
-}
-
-ivec3 __postDecr(inout ivec3 v)
-{
- __retVal = v;
- v = v - ivec3(1);
-}
-
-ivec4 __postDecr(inout ivec4 v)
-{
- __retVal = v;
- v = v - ivec4(1);
-}
-
-
-float __postDecr(inout float a)
-{
- __retVal = a;
- a = a - 1.0;
-}
-
-vec2 __postDecr(inout vec2 v)
-{
- __retVal = v;
- v = v - vec2(1.0);
-}
-
-vec3 __postDecr(inout vec3 v)
-{
- __retVal = v;
- v = v - vec3(1.0);
-}
-
-vec4 __postDecr(inout vec4 v)
-{
- __retVal = v;
- v = v - vec4(1.0);
-}
-
-
-mat2 __postDecr(inout mat2 m)
-{
- __retVal = m;
- m[0] = m[0] - vec2(1.0);
- m[1] = m[1] - vec2(1.0);
-}
-
-mat3 __postDecr(inout mat3 m)
-{
- __retVal = m;
- m[0] = m[0] - vec3(1.0);
- m[1] = m[1] - vec3(1.0);
- m[2] = m[2] - vec3(1.0);
-}
-
-mat4 __postDecr(inout mat4 m)
-{
- __retVal = m;
- m[0] = m[0] - vec4(1.0);
- m[1] = m[1] - vec4(1.0);
- m[2] = m[2] - vec4(1.0);
- m[3] = m[3] - vec4(1.0);
-}
-
-
-//// post-increment
-
-float __postIncr(inout float a)
-{
- __retVal = a;
- a = a + 1;
-}
-
-vec2 __postIncr(inout vec2 v)
-{
- __retVal = v;
- v = v + vec2(1.0);
-}
-
-vec3 __postIncr(inout vec3 v)
-{
- __retVal = v;
- v = v + vec3(1.0);
-}
-
-vec4 __postIncr(inout vec4 v)
-{
- __retVal = v;
- v = v + vec4(1.0);
-}
-
-
-int __postIncr(inout int a)
-{
- __retVal = a;
- a = a + 1;
-}
-
-ivec2 __postIncr(inout ivec2 v)
-{
- __retVal = v;
- v = v + ivec2(1);
-}
-
-ivec3 __postIncr(inout ivec3 v)
-{
- __retVal = v;
- v = v + ivec3(1);
-}
-
-ivec4 __postIncr(inout ivec4 v)
-{
- __retVal = v;
- v = v + ivec3(1);
-}
-
-
-mat2 __postIncr(inout mat2 m)
-{
- mat2 n = m;
- m[0] = m[0] + vec2(1.0);
- m[1] = m[1] + vec2(1.0);
- return n;
-}
-
-mat3 __postIncr(inout mat3 m)
-{
- mat3 n = m;
- m[0] = m[0] + vec3(1.0);
- m[1] = m[1] + vec3(1.0);
- m[2] = m[2] + vec3(1.0);
- return n;
-}
-
-mat4 __postIncr(inout mat4 m)
-{
- mat4 n = m;
- m[0] = m[0] + vec4(1.0);
- m[1] = m[1] + vec4(1.0);
- m[2] = m[2] + vec4(1.0);
- m[3] = m[3] + vec4(1.0);
- return n;
-}
-
-
-
-//// inequality operators
-
-
-// XXX are the inequality operators for floats/ints really needed????
-bool __operator < (const float a, const float b)
-{
- __asm vec4_sgt __retVal.x, b, a;
-}
-
-
-bool __operator < (const int a, const int b) {
- return float (a) < float (b);
-}
-
-bool __operator > (const float a, const float b) {
- bool c;
- __asm float_less c, b, a;
- return c;
-}
-
-bool __operator > (const int a, const int b) {
- return float (a) > float (b);
-}
-
-bool __operator >= (const float a, const float b) {
- bool g, e;
- __asm float_less g, b, a;
- __asm float_equal e, a, b;
- return g || e;
-}
-
-bool __operator >= (const int a, const int b) {
- return float (a) >= float (b);
-}
-
-bool __operator <= (const float a, const float b) {
- bool g, e;
- __asm float_less g, a, b;
- __asm float_equal e, a, b;
- return g || e;
-}
-
-bool __operator <= (const int a, const int b) {
- return float (a) <= float (b);
-}
-
-
-
-//
-// MESA-specific extension functions.
-//
-
-void printMESA (const float f) {
- __asm float_print f;
-}
-
-void printMESA (const int i) {
- __asm int_print i;
-}
-
-void printMESA (const bool b) {
- __asm bool_print b;
-}
-
-void printMESA (const vec2 v) {
- printMESA (v.x);
- printMESA (v.y);
-}
-
-void printMESA (const vec3 v) {
- printMESA (v.x);
- printMESA (v.y);
- printMESA (v.z);
-}
-
-void printMESA (const vec4 v) {
- printMESA (v.x);
- printMESA (v.y);
- printMESA (v.z);
- printMESA (v.w);
-}
-
-void printMESA (const ivec2 v) {
- printMESA (v.x);
- printMESA (v.y);
-}
-
-void printMESA (const ivec3 v) {
- printMESA (v.x);
- printMESA (v.y);
- printMESA (v.z);
-}
-
-void printMESA (const ivec4 v) {
- printMESA (v.x);
- printMESA (v.y);
- printMESA (v.z);
- printMESA (v.w);
-}
-
-void printMESA (const bvec2 v) {
- printMESA (v.x);
- printMESA (v.y);
-}
-
-void printMESA (const bvec3 v) {
- printMESA (v.x);
- printMESA (v.y);
- printMESA (v.z);
-}
-
-void printMESA (const bvec4 v) {
- printMESA (v.x);
- printMESA (v.y);
- printMESA (v.z);
- printMESA (v.w);
-}
-
-void printMESA (const mat2 m) {
- printMESA (m[0]);
- printMESA (m[1]);
-}
-
-void printMESA (const mat3 m) {
- printMESA (m[0]);
- printMESA (m[1]);
- printMESA (m[2]);
-}
-
-void printMESA (const mat4 m) {
- printMESA (m[0]);
- printMESA (m[1]);
- printMESA (m[2]);
- printMESA (m[3]);
-}
-
-void printMESA (const sampler1D e) {
- __asm int_print e;
-}
-
-void printMESA (const sampler2D e) {
- __asm int_print e;
-}
-
-void printMESA (const sampler3D e) {
- __asm int_print e;
-}
-
-void printMESA (const samplerCube e) {
- __asm int_print e;
-}
-
-void printMESA (const sampler1DShadow e) {
- __asm int_print e;
-}
-
-void printMESA (const sampler2DShadow e) {
- __asm int_print e;
-}
-
diff --git a/src/mesa/slang/library/slang_fragment_builtin.gc b/src/mesa/slang/library/slang_fragment_builtin.gc
deleted file mode 100644
index 54a80ea0e06..00000000000
--- a/src/mesa/slang/library/slang_fragment_builtin.gc
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 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.
- */
-
-//
-// From Shader Spec, ver. 1.10, rev. 59
-//
-
-__fixed_input vec4 gl_FragCoord;
-__fixed_input bool gl_FrontFacing;
-__fixed_output vec4 gl_FragColor;
-__fixed_output vec4 gl_FragData[gl_MaxDrawBuffers];
-__fixed_output float gl_FragDepth;
-
-varying vec4 gl_Color;
-varying vec4 gl_SecondaryColor;
-varying vec4 gl_TexCoord[gl_MaxTextureCoords];
-varying float gl_FogFragCoord;
-
-
-
-//// 8.7 Texture Lookup Functions (with bias)
-
-vec4 texture1D(const sampler1D sampler, const float coord, const float bias)
-{
- vec4 coord4;
- coord4.x = coord;
- coord4.w = bias;
- __asm vec4_tex_1d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture1DProj(const sampler1D sampler, const vec2 coord, const float bias)
-{
- // do projection here (there's no vec4_texbp1d instruction)
- vec4 pcoord;
- pcoord.x = coord.x / coord.y;
- pcoord.w = bias;
- __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
-}
-
-vec4 texture1DProj(const sampler1D sampler, const vec4 coord, const float bias)
-{
- // do projection here (there's no vec4_texbp1d instruction)
- vec4 pcoord;
- pcoord.x = coord.x / coord.z;
- pcoord.w = bias;
- __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
-}
-
-
-
-
-vec4 texture2D(const sampler2D sampler, const vec2 coord, const float bias)
-{
- vec4 coord4;
- coord4.xy = coord.xy;
- coord4.w = bias;
- __asm vec4_tex_2d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture2DProj(const sampler2D sampler, const vec3 coord, const float bias)
-{
- // do projection here (there's no vec4_texbp2d instruction)
- vec4 pcoord;
- pcoord.xy = coord.xy / coord.z;
- pcoord.w = bias;
- __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
-}
-
-vec4 texture2DProj(const sampler2D sampler, const vec4 coord, const float bias)
-{
- // do projection here (there's no vec4_texbp2d instruction)
- vec4 pcoord;
- pcoord.xy = coord.xy / coord.w;
- pcoord.w = bias;
- __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
-}
-
-
-
-
-vec4 texture3D(const sampler3D sampler, const vec3 coord, const float bias)
-{
- vec4 coord4;
- coord4.xyz = coord.xyz;
- coord4.w = bias;
- __asm vec4_tex_3d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture3DProj(const sampler3D sampler, const vec4 coord, const float bias)
-{
- // do projection here (there's no vec4_texbp3d instruction)
- vec4 pcoord;
- pcoord.xyz = coord.xyz / coord.w;
- pcoord.w = bias;
- __asm vec4_tex_3d_bias __retVal, sampler, pcoord;
-}
-
-
-
-
-vec4 textureCube(const samplerCube sampler, const vec3 coord, const float bias)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = bias;
- __asm vec4_tex_cube __retVal, sampler, coord4;
-}
-
-
-
-vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord, const float bias)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = bias;
- __asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord, const float bias)
-{
- vec4 pcoord;
- pcoord.x = coord.x / coord.w;
- pcoord.z = coord.z;
- pcoord.w = bias;
- __asm vec4_tex_1d_bias_shadow __retVal, sampler, pcoord;
-}
-
-vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord, const float bias)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = bias;
- __asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord, const float bias)
-{
- vec4 pcoord;
- pcoord.xy = coord.xy / coord.w;
- pcoord.z = coord.z;
- pcoord.w = bias;
- __asm vec4_tex_2d_bias_shadow __retVal, sampler, pcoord;
-}
-
-
-
-//// GL_EXT_texture_array
-
-vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord)
-{
- vec4 coord4;
- coord4.xy = coord;
- __asm vec4_tex_1d_array __retVal, sampler, coord4;
-}
-
-vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord, const float bias)
-{
- vec4 coord4;
- coord4.xy = coord;
- coord4.w = bias;
- __asm vec4_tex_1d_array_bias __retVal, sampler, coord4;
-}
-
-vec4 texure2DArray(const sampler2DArray sampler, const vec3 coord)
-{
- vec4 coord4;
- coord4.xyz = coord;
- __asm vec4_tex_2d_array __retVal, sampler, coord4;
-}
-
-vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord, const float bias)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = bias;
- __asm vec4_tex_2d_array_bias __retVal, sampler, coord4;
-}
-
-vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord)
-{
- vec4 coord4;
- coord4.xy = coord;
- __asm vec4_tex_1d_array_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord, const float bias)
-{
- vec4 coord4;
- coord4.xy = coord;
- coord4.w = bias;
- __asm vec4_tex_1d_array_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord)
-{
- vec4 coord4;
- coord4.xyz = coord;
- __asm vec4_tex_2d_array_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord, const float bias)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = bias;
- __asm vec4_tex_2d_array_bias_shadow __retVal, sampler, coord4;
-}
-
-
-
-//
-// 8.8 Fragment Processing Functions
-//
-
-float dFdx(const float p)
-{
- __asm vec4_ddx __retVal.x, p.xxxx;
-}
-
-vec2 dFdx(const vec2 p)
-{
- __asm vec4_ddx __retVal.xy, p.xyyy;
-}
-
-vec3 dFdx(const vec3 p)
-{
- __asm vec4_ddx __retVal.xyz, p.xyzz;
-}
-
-vec4 dFdx(const vec4 p)
-{
- __asm vec4_ddx __retVal, p;
-}
-
-float dFdy(const float p)
-{
- __asm vec4_ddy __retVal.x, p.xxxx;
-}
-
-vec2 dFdy(const vec2 p)
-{
- __asm vec4_ddy __retVal.xy, p.xyyy;
-}
-
-vec3 dFdy(const vec3 p)
-{
- __asm vec4_ddy __retVal.xyz, p.xyzz;
-}
-
-vec4 dFdy(const vec4 p)
-{
- __asm vec4_ddy __retVal, p;
-}
-
-float fwidth (const float p)
-{
- // XXX hand-write with __asm
- return abs(dFdx(p)) + abs(dFdy(p));
-}
-
-vec2 fwidth(const vec2 p)
-{
- // XXX hand-write with __asm
- return abs(dFdx(p)) + abs(dFdy(p));
-}
-
-vec3 fwidth(const vec3 p)
-{
- // XXX hand-write with __asm
- return abs(dFdx(p)) + abs(dFdy(p));
-}
-
-vec4 fwidth(const vec4 p)
-{
- // XXX hand-write with __asm
- return abs(dFdx(p)) + abs(dFdy(p));
-}
-
diff --git a/src/mesa/slang/library/slang_geometry_builtin.gc b/src/mesa/slang/library/slang_geometry_builtin.gc
deleted file mode 100644
index 07524912ba1..00000000000
--- a/src/mesa/slang/library/slang_geometry_builtin.gc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * 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.
- */
-
-const int _mesa_VerticesInMax = 6;
-
-__fixed_input int gl_PrimitiveIDIn;
-__fixed_output int gl_PrimitiveID;
-__fixed_output int gl_Layer;
-
-
-varying in vec4 gl_FrontColorIn[_mesa_VerticesInMax];
-varying in vec4 gl_BackColorIn[_mesa_VerticesInMax];
-varying in vec4 gl_FrontSecondaryColorIn[_mesa_VerticesInMax];
-varying in vec4 gl_BackSecondaryColorIn[_mesa_VerticesInMax];
-/*varying in vec4 gl_TexCoordIn[_mesa_VerticesInMax][gl_MaxTextureCoords];*/
-varying in float gl_FogFragCoordIn[_mesa_VerticesInMax];
-varying in vec4 gl_PositionIn[_mesa_VerticesInMax];
-varying in float gl_PointSizeIn[_mesa_VerticesInMax];
-varying in vec4 gl_ClipVertexIn[_mesa_VerticesInMax];
-
-varying out vec4 gl_Position;
-varying out vec4 gl_FrontColor;
-varying out vec4 gl_BackColor;
-varying out vec4 gl_FrontSecondaryColor;
-varying out vec4 gl_BackSecondaryColor;
-varying out vec4 gl_TexCoord[gl_MaxTextureCoords];
-varying out float gl_FogFragCoord;
-
-void EmitVertex()
-{
- __asm emit_vertex;
-}
-
-void EndPrimitive()
-{
- __asm end_primitive;
-}
diff --git a/src/mesa/slang/library/slang_vertex_builtin.gc b/src/mesa/slang/library/slang_vertex_builtin.gc
deleted file mode 100644
index 0c67c2ef20d..00000000000
--- a/src/mesa/slang/library/slang_vertex_builtin.gc
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 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.
- */
-
-//
-// From Shader Spec, ver. 1.10, rev. 59
-//
-
-__fixed_output vec4 gl_Position;
-__fixed_output float gl_PointSize;
-__fixed_output vec4 gl_ClipVertex;
-
-attribute vec4 gl_Color;
-attribute vec4 gl_SecondaryColor;
-attribute vec3 gl_Normal;
-attribute vec4 gl_Vertex;
-attribute vec4 gl_MultiTexCoord0;
-attribute vec4 gl_MultiTexCoord1;
-attribute vec4 gl_MultiTexCoord2;
-attribute vec4 gl_MultiTexCoord3;
-attribute vec4 gl_MultiTexCoord4;
-attribute vec4 gl_MultiTexCoord5;
-attribute vec4 gl_MultiTexCoord6;
-attribute vec4 gl_MultiTexCoord7;
-attribute float gl_FogCoord;
-
-varying vec4 gl_FrontColor;
-varying vec4 gl_BackColor;
-varying vec4 gl_FrontSecondaryColor;
-varying vec4 gl_BackSecondaryColor;
-varying vec4 gl_TexCoord[gl_MaxTextureCoords];
-varying float gl_FogFragCoord;
-
-//
-// Geometric Functions
-//
-
-vec4 ftransform()
-{
- __retVal = gl_ModelViewProjectionMatrix[0] * gl_Vertex.xxxx
- + gl_ModelViewProjectionMatrix[1] * gl_Vertex.yyyy
- + gl_ModelViewProjectionMatrix[2] * gl_Vertex.zzzz
- + gl_ModelViewProjectionMatrix[3] * gl_Vertex.wwww;
-}
-
-
-
-//
-// 8.7 Texture Lookup Functions
-// These are pretty much identical to the ones in slang_fragment_builtin.gc
-// When used in a vertex program, the texture sample instructions should not
-// be using a LOD term so it's effectively zero. Adding 'lod' to that does
-// what we want.
-//
-
-vec4 texture1DLod(const sampler1D sampler, const float coord, const float lod)
-{
- vec4 coord4;
- coord4.x = coord;
- coord4.w = lod;
- __asm vec4_tex_1d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture1DProjLod(const sampler1D sampler, const vec2 coord, const float lod)
-{
- vec4 pcoord;
- pcoord.x = coord.x / coord.y;
- pcoord.w = lod;
- __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
-}
-
-vec4 texture1DProjLod(const sampler1D sampler, const vec4 coord, const float lod)
-{
- vec4 pcoord;
- pcoord.x = coord.x / coord.z;
- pcoord.w = lod;
- __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
-}
-
-
-
-vec4 texture2DLod(const sampler2D sampler, const vec2 coord, const float lod)
-{
- vec4 coord4;
- coord4.xy = coord.xy;
- coord4.w = lod;
- __asm vec4_tex_2d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture2DProjLod(const sampler2D sampler, const vec3 coord, const float lod)
-{
- vec4 pcoord;
- pcoord.xy = coord.xy / coord.z;
- pcoord.w = lod;
- __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
-}
-
-vec4 texture2DProjLod(const sampler2D sampler, const vec4 coord, const float lod)
-{
- vec4 pcoord;
- pcoord.xy = coord.xy / coord.z;
- pcoord.w = lod;
- __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
-}
-
-
-vec4 texture3DLod(const sampler3D sampler, const vec3 coord, const float lod)
-{
- vec4 coord4;
- coord4.xyz = coord.xyz;
- coord4.w = lod;
- __asm vec4_tex_3d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture3DProjLod(const sampler3D sampler, const vec4 coord, const float lod)
-{
- // do projection here (there's no vec4_tex_3d_bias_proj instruction)
- vec4 pcoord;
- pcoord.xyz = coord.xyz / coord.w;
- pcoord.w = lod;
- __asm vec4_tex_3d_bias __retVal, sampler, pcoord;
-}
-
-
-vec4 textureCubeLod(const samplerCube sampler, const vec3 coord, const float lod)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = lod;
- __asm vec4_tex_cube __retVal, sampler, coord4;
-}
-
-
-vec4 shadow1DLod(const sampler1DShadow sampler, const vec3 coord, const float lod)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = lod;
- __asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow1DProjLod(const sampler1DShadow sampler, const vec4 coord,
- const float lod)
-{
- vec4 pcoord;
- pcoord.x = coord.x / coord.w;
- pcoord.z = coord.z;
- pcoord.w = lod;
- __asm vec4_tex_1d_bias_shadow __retVal, sampler, pcoord;
-}
-
-
-vec4 shadow2DLod(const sampler2DShadow sampler, const vec3 coord, const float lod)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = lod;
- __asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow2DProjLod(const sampler2DShadow sampler, const vec4 coord,
- const float lod)
-{
- vec4 pcoord;
- pcoord.xy = coord.xy / coord.w;
- pcoord.z = coord.z;
- pcoord.w = lod;
- __asm vec4_tex_2d_bias_shadow __retVal, sampler, pcoord;
-}
-
-
-//// GL_EXT_texture_array
-
-vec4 texture1DArrayLod(const sampler1DArray sampler, const vec2 coord, const float lod)
-{
- vec4 coord4;
- coord4.xy = coord;
- coord4.w = lod;
- __asm vec4_tex_1d_array_bias __retVal, sampler, coord4;
-}
-
-
-vec4 texture2DArrayLod(const sampler2DArray sampler, const vec3 coord, const float lod)
-{
- vec4 coord4;
- coord4.xyz = coord;
- coord4.w = lod;
- __asm vec4_tex_2d_array_bias __retVal, sampler, coord4;
-}
-
diff --git a/src/mesa/slang/slang_builtin.c b/src/mesa/slang/slang_builtin.c
deleted file mode 100644
index a7e0efcb7b5..00000000000
--- a/src/mesa/slang/slang_builtin.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
- * Copyright (C) 2008 VMware, 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.
- */
-
-/**
- * \file slang_builtin.c
- * Resolve built-in uniform vars.
- * \author Brian Paul
- */
-
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "program/program.h"
-#include "program/prog_instruction.h"
-#include "program/prog_parameter.h"
-#include "program/prog_statevars.h"
-#include "slang/slang_ir.h"
-#include "slang/slang_builtin.h"
-
-
-/** special state token (see below) */
-#define STATE_ARRAY ((gl_state_index) 0xfffff)
-
-
-/**
- * Lookup GL state given a variable name, 0, 1 or 2 indexes and a field.
- * Allocate room for the state in the given param list and return position
- * in the list.
- * Yes, this is kind of ugly, but it works.
- */
-static GLint
-lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
- GLuint *swizzleOut,
- struct gl_program_parameter_list *paramList)
-{
- /*
- * NOTE: The ARB_vertex_program extension specified that matrices get
- * loaded in registers in row-major order. With GLSL, we want column-
- * major order. So, we need to transpose all matrices here...
- */
- static const struct {
- const char *name;
- gl_state_index matrix;
- gl_state_index modifier;
- } matrices[] = {
- { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
- { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
- { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
- { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
-
- { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
- { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
- { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
- { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
-
- { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
- { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
- { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
- { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
-
- { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
- { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
- { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
- { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
-
- { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
-
- { NULL, 0, 0 }
- };
- gl_state_index tokens[STATE_LENGTH];
- GLuint i;
- GLboolean isMatrix = GL_FALSE;
-
- for (i = 0; i < STATE_LENGTH; i++) {
- tokens[i] = 0;
- }
- *swizzleOut = SWIZZLE_NOOP;
-
- /* first, look if var is a pre-defined matrix */
- for (i = 0; matrices[i].name; i++) {
- if (strcmp(var, matrices[i].name) == 0) {
- tokens[0] = matrices[i].matrix;
- /* tokens[1], [2] and [3] filled below */
- tokens[4] = matrices[i].modifier;
- isMatrix = GL_TRUE;
- break;
- }
- }
-
- if (isMatrix) {
- if (tokens[0] == STATE_TEXTURE_MATRIX) {
- /* texture_matrix[index1][index2] */
- tokens[1] = index1 >= 0 ? index1 : 0; /* which texture matrix */
- index1 = index2; /* move matrix row value to index1 */
- }
- if (index1 < 0) {
- /* index1 is unused: prevent extra addition at end of function */
- index1 = 0;
- }
- }
- else if (strcmp(var, "gl_DepthRange") == 0) {
- tokens[0] = STATE_DEPTH_RANGE;
- assert(field);
- if (strcmp(field, "near") == 0) {
- *swizzleOut = SWIZZLE_XXXX;
- }
- else if (strcmp(field, "far") == 0) {
- *swizzleOut = SWIZZLE_YYYY;
- }
- else if (strcmp(field, "diff") == 0) {
- *swizzleOut = SWIZZLE_ZZZZ;
- }
- else {
- return -1;
- }
- }
- else if (strcmp(var, "gl_ClipPlane") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_CLIPPLANE;
- tokens[1] = index1;
- }
- else if (strcmp(var, "gl_Point") == 0) {
- assert(field);
- if (strcmp(field, "size") == 0) {
- tokens[0] = STATE_POINT_SIZE;
- *swizzleOut = SWIZZLE_XXXX;
- }
- else if (strcmp(field, "sizeMin") == 0) {
- tokens[0] = STATE_POINT_SIZE;
- *swizzleOut = SWIZZLE_YYYY;
- }
- else if (strcmp(field, "sizeMax") == 0) {
- tokens[0] = STATE_POINT_SIZE;
- *swizzleOut = SWIZZLE_ZZZZ;
- }
- else if (strcmp(field, "fadeThresholdSize") == 0) {
- tokens[0] = STATE_POINT_SIZE;
- *swizzleOut = SWIZZLE_WWWW;
- }
- else if (strcmp(field, "distanceConstantAttenuation") == 0) {
- tokens[0] = STATE_POINT_ATTENUATION;
- *swizzleOut = SWIZZLE_XXXX;
- }
- else if (strcmp(field, "distanceLinearAttenuation") == 0) {
- tokens[0] = STATE_POINT_ATTENUATION;
- *swizzleOut = SWIZZLE_YYYY;
- }
- else if (strcmp(field, "distanceQuadraticAttenuation") == 0) {
- tokens[0] = STATE_POINT_ATTENUATION;
- *swizzleOut = SWIZZLE_ZZZZ;
- }
- else {
- return -1;
- }
- }
- else if (strcmp(var, "gl_FrontMaterial") == 0 ||
- strcmp(var, "gl_BackMaterial") == 0) {
- tokens[0] = STATE_MATERIAL;
- if (strcmp(var, "gl_FrontMaterial") == 0)
- tokens[1] = 0;
- else
- tokens[1] = 1;
- assert(field);
- if (strcmp(field, "emission") == 0) {
- tokens[2] = STATE_EMISSION;
- }
- else if (strcmp(field, "ambient") == 0) {
- tokens[2] = STATE_AMBIENT;
- }
- else if (strcmp(field, "diffuse") == 0) {
- tokens[2] = STATE_DIFFUSE;
- }
- else if (strcmp(field, "specular") == 0) {
- tokens[2] = STATE_SPECULAR;
- }
- else if (strcmp(field, "shininess") == 0) {
- tokens[2] = STATE_SHININESS;
- *swizzleOut = SWIZZLE_XXXX;
- }
- else {
- return -1;
- }
- }
- else if (strcmp(var, "gl_LightSource") == 0) {
- if (!field || index1 < 0)
- return -1;
-
- tokens[0] = STATE_LIGHT;
- tokens[1] = index1;
-
- if (strcmp(field, "ambient") == 0) {
- tokens[2] = STATE_AMBIENT;
- }
- else if (strcmp(field, "diffuse") == 0) {
- tokens[2] = STATE_DIFFUSE;
- }
- else if (strcmp(field, "specular") == 0) {
- tokens[2] = STATE_SPECULAR;
- }
- else if (strcmp(field, "position") == 0) {
- tokens[2] = STATE_POSITION;
- }
- else if (strcmp(field, "halfVector") == 0) {
- tokens[2] = STATE_HALF_VECTOR;
- }
- else if (strcmp(field, "spotDirection") == 0) {
- tokens[2] = STATE_SPOT_DIRECTION;
- }
- else if (strcmp(field, "spotCosCutoff") == 0) {
- tokens[2] = STATE_SPOT_DIRECTION;
- *swizzleOut = SWIZZLE_WWWW;
- }
- else if (strcmp(field, "spotCutoff") == 0) {
- tokens[2] = STATE_SPOT_CUTOFF;
- *swizzleOut = SWIZZLE_XXXX;
- }
- else if (strcmp(field, "spotExponent") == 0) {
- tokens[2] = STATE_ATTENUATION;
- *swizzleOut = SWIZZLE_WWWW;
- }
- else if (strcmp(field, "constantAttenuation") == 0) {
- tokens[2] = STATE_ATTENUATION;
- *swizzleOut = SWIZZLE_XXXX;
- }
- else if (strcmp(field, "linearAttenuation") == 0) {
- tokens[2] = STATE_ATTENUATION;
- *swizzleOut = SWIZZLE_YYYY;
- }
- else if (strcmp(field, "quadraticAttenuation") == 0) {
- tokens[2] = STATE_ATTENUATION;
- *swizzleOut = SWIZZLE_ZZZZ;
- }
- else {
- return -1;
- }
- }
- else if (strcmp(var, "gl_LightModel") == 0) {
- if (strcmp(field, "ambient") == 0) {
- tokens[0] = STATE_LIGHTMODEL_AMBIENT;
- }
- else {
- return -1;
- }
- }
- else if (strcmp(var, "gl_FrontLightModelProduct") == 0) {
- if (strcmp(field, "sceneColor") == 0) {
- tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
- tokens[1] = 0;
- }
- else {
- return -1;
- }
- }
- else if (strcmp(var, "gl_BackLightModelProduct") == 0) {
- if (strcmp(field, "sceneColor") == 0) {
- tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
- tokens[1] = 1;
- }
- else {
- return -1;
- }
- }
- else if (strcmp(var, "gl_FrontLightProduct") == 0 ||
- strcmp(var, "gl_BackLightProduct") == 0) {
- if (index1 < 0 || !field)
- return -1;
-
- tokens[0] = STATE_LIGHTPROD;
- tokens[1] = index1; /* light number */
- if (strcmp(var, "gl_FrontLightProduct") == 0) {
- tokens[2] = 0; /* front */
- }
- else {
- tokens[2] = 1; /* back */
- }
- if (strcmp(field, "ambient") == 0) {
- tokens[3] = STATE_AMBIENT;
- }
- else if (strcmp(field, "diffuse") == 0) {
- tokens[3] = STATE_DIFFUSE;
- }
- else if (strcmp(field, "specular") == 0) {
- tokens[3] = STATE_SPECULAR;
- }
- else {
- return -1;
- }
- }
- else if (strcmp(var, "gl_TextureEnvColor") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXENV_COLOR;
- tokens[1] = index1;
- }
- else if (strcmp(var, "gl_EyePlaneS") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXGEN;
- tokens[1] = index1; /* tex unit */
- tokens[2] = STATE_TEXGEN_EYE_S;
- }
- else if (strcmp(var, "gl_EyePlaneT") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXGEN;
- tokens[1] = index1; /* tex unit */
- tokens[2] = STATE_TEXGEN_EYE_T;
- }
- else if (strcmp(var, "gl_EyePlaneR") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXGEN;
- tokens[1] = index1; /* tex unit */
- tokens[2] = STATE_TEXGEN_EYE_R;
- }
- else if (strcmp(var, "gl_EyePlaneQ") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXGEN;
- tokens[1] = index1; /* tex unit */
- tokens[2] = STATE_TEXGEN_EYE_Q;
- }
- else if (strcmp(var, "gl_ObjectPlaneS") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXGEN;
- tokens[1] = index1; /* tex unit */
- tokens[2] = STATE_TEXGEN_OBJECT_S;
- }
- else if (strcmp(var, "gl_ObjectPlaneT") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXGEN;
- tokens[1] = index1; /* tex unit */
- tokens[2] = STATE_TEXGEN_OBJECT_T;
- }
- else if (strcmp(var, "gl_ObjectPlaneR") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXGEN;
- tokens[1] = index1; /* tex unit */
- tokens[2] = STATE_TEXGEN_OBJECT_R;
- }
- else if (strcmp(var, "gl_ObjectPlaneQ") == 0) {
- if (index1 < 0)
- return -1;
- tokens[0] = STATE_TEXGEN;
- tokens[1] = index1; /* tex unit */
- tokens[2] = STATE_TEXGEN_OBJECT_Q;
- }
- else if (strcmp(var, "gl_Fog") == 0) {
- if (strcmp(field, "color") == 0) {
- tokens[0] = STATE_FOG_COLOR;
- }
- else if (strcmp(field, "density") == 0) {
- tokens[0] = STATE_FOG_PARAMS;
- *swizzleOut = SWIZZLE_XXXX;
- }
- else if (strcmp(field, "start") == 0) {
- tokens[0] = STATE_FOG_PARAMS;
- *swizzleOut = SWIZZLE_YYYY;
- }
- else if (strcmp(field, "end") == 0) {
- tokens[0] = STATE_FOG_PARAMS;
- *swizzleOut = SWIZZLE_ZZZZ;
- }
- else if (strcmp(field, "scale") == 0) {
- tokens[0] = STATE_FOG_PARAMS;
- *swizzleOut = SWIZZLE_WWWW;
- }
- else {
- return -1;
- }
- }
- else {
- return -1;
- }
-
- if (isMatrix) {
- /* load all four rows (or columns) of matrix */
- GLint pos[4];
- GLuint j;
- for (j = 0; j < 4; j++) {
- tokens[2] = tokens[3] = j; /* jth row of matrix */
- pos[j] = _mesa_add_state_reference(paramList, tokens);
- assert(pos[j] >= 0);
- ASSERT(pos[j] >= 0);
- }
- return pos[0] + index1;
- }
- else {
- /* allocate a single register */
- GLint pos = _mesa_add_state_reference(paramList, tokens);
- ASSERT(pos >= 0);
- return pos;
- }
-}
-
-
-
-/**
- * Given a variable name and datatype, emit uniform/constant buffer
- * entries which will store that state variable.
- * For example, if name="gl_LightSource" we'll emit 64 state variable
- * vectors/references and return position where that data starts. This will
- * allow run-time array indexing into the light source array.
- *
- * Note that this is a recursive function.
- *
- * \return -1 if error, else index of start of data in the program parameter list
- */
-static GLint
-emit_statevars(const char *name, int array_len,
- const slang_type_specifier *type,
- gl_state_index tokens[STATE_LENGTH],
- struct gl_program_parameter_list *paramList)
-{
- if (type->type == SLANG_SPEC_ARRAY) {
- GLint i, pos = -1;
- assert(array_len > 0);
- if (strcmp(name, "gl_ClipPlane") == 0) {
- tokens[0] = STATE_CLIPPLANE;
- }
- else if (strcmp(name, "gl_LightSource") == 0) {
- tokens[0] = STATE_LIGHT;
- }
- else if (strcmp(name, "gl_FrontLightProduct") == 0) {
- tokens[0] = STATE_LIGHTPROD;
- tokens[2] = 0; /* front */
- }
- else if (strcmp(name, "gl_BackLightProduct") == 0) {
- tokens[0] = STATE_LIGHTPROD;
- tokens[2] = 1; /* back */
- }
- else if (strcmp(name, "gl_TextureEnvColor") == 0) {
- tokens[0] = STATE_TEXENV_COLOR;
- }
- else if (strcmp(name, "gl_EyePlaneS") == 0) {
- tokens[0] = STATE_TEXGEN;
- tokens[2] = STATE_TEXGEN_EYE_S;
- }
- else if (strcmp(name, "gl_EyePlaneT") == 0) {
- tokens[0] = STATE_TEXGEN;
- tokens[2] = STATE_TEXGEN_EYE_T;
- }
- else if (strcmp(name, "gl_EyePlaneR") == 0) {
- tokens[0] = STATE_TEXGEN;
- tokens[2] = STATE_TEXGEN_EYE_R;
- }
- else if (strcmp(name, "gl_EyePlaneQ") == 0) {
- tokens[0] = STATE_TEXGEN;
- tokens[2] = STATE_TEXGEN_EYE_Q;
- }
- else if (strcmp(name, "gl_ObjectPlaneS") == 0) {
- tokens[0] = STATE_TEXGEN;
- tokens[2] = STATE_TEXGEN_OBJECT_S;
- }
- else if (strcmp(name, "gl_ObjectPlaneT") == 0) {
- tokens[0] = STATE_TEXGEN;
- tokens[2] = STATE_TEXGEN_OBJECT_T;
- }
- else if (strcmp(name, "gl_ObjectPlaneR") == 0) {
- tokens[0] = STATE_TEXGEN;
- tokens[2] = STATE_TEXGEN_OBJECT_R;
- }
- else if (strcmp(name, "gl_ObjectPlaneQ") == 0) {
- tokens[0] = STATE_TEXGEN;
- tokens[2] = STATE_TEXGEN_OBJECT_Q;
- }
- else if (strcmp(name, "gl_TextureMatrix") == 0) {
- tokens[0] = STATE_TEXTURE_MATRIX;
- tokens[4] = STATE_MATRIX_TRANSPOSE;
- }
- else if (strcmp(name, "gl_TextureMatrixInverse") == 0) {
- tokens[0] = STATE_TEXTURE_MATRIX;
- tokens[4] = STATE_MATRIX_INVTRANS;
- }
- else if (strcmp(name, "gl_TextureMatrixTranspose") == 0) {
- tokens[0] = STATE_TEXTURE_MATRIX;
- tokens[4] = 0;
- }
- else if (strcmp(name, "gl_TextureMatrixInverseTranspose") == 0) {
- tokens[0] = STATE_TEXTURE_MATRIX;
- tokens[4] = STATE_MATRIX_INVERSE;
- }
- else {
- return -1; /* invalid array name */
- }
- /* emit state vars for each array element */
- for (i = 0; i < array_len; i++) {
- GLint p;
- tokens[1] = i;
- p = emit_statevars(NULL, 0, type->_array, tokens, paramList);
- if (i == 0)
- pos = p;
- }
- return pos;
- }
- else if (type->type == SLANG_SPEC_STRUCT) {
- const slang_variable_scope *fields = type->_struct->fields;
- GLuint i, pos = 0;
- for (i = 0; i < fields->num_variables; i++) {
- const slang_variable *var = fields->variables[i];
- GLint p = emit_statevars(var->a_name, 0, &var->type.specifier,
- tokens, paramList);
- if (i == 0)
- pos = p;
- }
- return pos;
- }
- else if (type->type == SLANG_SPEC_MAT4) {
- /* unroll/emit 4 array rows (or columns) */
- slang_type_specifier vec4;
- GLint i, p, pos = -1;
- vec4.type = SLANG_SPEC_VEC4;
- for (i = 0; i < 4; i++) {
- tokens[2] = tokens[3] = i; /* row[i] (or column[i]) of matrix */
- p = emit_statevars(NULL, 0, &vec4, tokens, paramList);
- if (pos == -1)
- pos = p;
- }
- return pos;
- }
- else {
- GLint pos;
- assert(type->type == SLANG_SPEC_VEC4 ||
- type->type == SLANG_SPEC_VEC3 ||
- type->type == SLANG_SPEC_VEC2 ||
- type->type == SLANG_SPEC_FLOAT ||
- type->type == SLANG_SPEC_IVEC4 ||
- type->type == SLANG_SPEC_IVEC3 ||
- type->type == SLANG_SPEC_IVEC2 ||
- type->type == SLANG_SPEC_INT);
- if (name) {
- GLint t;
-
- if (tokens[0] == STATE_LIGHT)
- t = 2;
- else if (tokens[0] == STATE_LIGHTPROD)
- t = 3;
- else
- return -1; /* invalid array name */
-
- if (strcmp(name, "ambient") == 0) {
- tokens[t] = STATE_AMBIENT;
- }
- else if (strcmp(name, "diffuse") == 0) {
- tokens[t] = STATE_DIFFUSE;
- }
- else if (strcmp(name, "specular") == 0) {
- tokens[t] = STATE_SPECULAR;
- }
- else if (strcmp(name, "position") == 0) {
- tokens[t] = STATE_POSITION;
- }
- else if (strcmp(name, "halfVector") == 0) {
- tokens[t] = STATE_HALF_VECTOR;
- }
- else if (strcmp(name, "spotDirection") == 0) {
- tokens[t] = STATE_SPOT_DIRECTION; /* xyz components */
- }
- else if (strcmp(name, "spotCosCutoff") == 0) {
- tokens[t] = STATE_SPOT_DIRECTION; /* w component */
- }
-
- else if (strcmp(name, "constantAttenuation") == 0) {
- tokens[t] = STATE_ATTENUATION; /* x component */
- }
- else if (strcmp(name, "linearAttenuation") == 0) {
- tokens[t] = STATE_ATTENUATION; /* y component */
- }
- else if (strcmp(name, "quadraticAttenuation") == 0) {
- tokens[t] = STATE_ATTENUATION; /* z component */
- }
- else if (strcmp(name, "spotExponent") == 0) {
- tokens[t] = STATE_ATTENUATION; /* w = spot exponent */
- }
-
- else if (strcmp(name, "spotCutoff") == 0) {
- tokens[t] = STATE_SPOT_CUTOFF; /* x component */
- }
-
- else {
- return -1; /* invalid field name */
- }
- }
-
- pos = _mesa_add_state_reference(paramList, tokens);
- return pos;
- }
-
- return 1;
-}
-
-
-/**
- * Unroll the named built-in uniform variable into a sequence of state
- * vars in the given parameter list.
- */
-static GLint
-alloc_state_var_array(const slang_variable *var,
- struct gl_program_parameter_list *paramList)
-{
- gl_state_index tokens[STATE_LENGTH];
- GLuint i;
- GLint pos;
-
- /* Initialize the state tokens array. This is very important.
- * When we call _mesa_add_state_reference() it'll searches the parameter
- * list to see if the given statevar token sequence is already present.
- * This is normally a good thing since it prevents redundant values in the
- * constant buffer.
- *
- * But when we're building arrays of state this can be bad. For example,
- * consider this fragment of GLSL code:
- * foo = gl_LightSource[3].diffuse;
- * ...
- * bar = gl_LightSource[i].diffuse;
- *
- * When we unroll the gl_LightSource array (for "bar") we want to re-emit
- * gl_LightSource[3].diffuse and not re-use the first instance (from "foo")
- * since that would upset the array layout. We handle this situation by
- * setting the last token in the state var token array to the special
- * value STATE_ARRAY.
- * This token will only be set for array state. We can hijack the last
- * element in the array for this since it's never used for light, clipplane
- * or texture env array state.
- */
- for (i = 0; i < STATE_LENGTH; i++)
- tokens[i] = 0;
- tokens[STATE_LENGTH - 1] = STATE_ARRAY;
-
- pos = emit_statevars(var->a_name, var->array_len, &var->type.specifier,
- tokens, paramList);
-
- return pos;
-}
-
-
-
-/**
- * Allocate storage for a pre-defined uniform (a GL state variable).
- * As a memory-saving optimization, we try to only allocate storage for
- * state vars that are actually used.
- *
- * Arrays such as gl_LightSource are handled specially. For an expression
- * like "gl_LightSource[2].diffuse", we can allocate a single uniform/constant
- * slot and return the index. In this case, we return direct=TRUE.
- *
- * Buf for something like "gl_LightSource[i].diffuse" we don't know the value
- * of 'i' at compile time so we need to "unroll" the gl_LightSource array
- * into a consecutive sequence of uniform/constant slots so it can be indexed
- * at runtime. In this case, we return direct=FALSE.
- *
- * Currently, all pre-defined uniforms are in one of these forms:
- * var
- * var[i]
- * var.field
- * var[i].field
- * var[i][j]
- *
- * \return -1 upon error, else position in paramList of the state variable/data
- */
-GLint
-_slang_alloc_statevar(slang_ir_node *n,
- struct gl_program_parameter_list *paramList,
- GLboolean *direct)
-{
- slang_ir_node *n0 = n;
- const char *field = NULL;
- GLint index1 = -1, index2 = -1;
- GLuint swizzle;
-
- *direct = GL_TRUE;
-
- if (n->Opcode == IR_FIELD) {
- field = n->Field;
- n = n->Children[0];
- }
-
- if (n->Opcode == IR_ELEMENT) {
- if (n->Children[1]->Opcode == IR_FLOAT) {
- index1 = (GLint) n->Children[1]->Value[0];
- }
- else {
- *direct = GL_FALSE;
- }
- n = n->Children[0];
- }
-
- if (n->Opcode == IR_ELEMENT) {
- /* XXX can only handle constant indexes for now */
- if (n->Children[1]->Opcode == IR_FLOAT) {
- /* two-dimensional array index: mat[i][j] */
- index2 = index1;
- index1 = (GLint) n->Children[1]->Value[0];
- }
- else {
- *direct = GL_FALSE;
- }
- n = n->Children[0];
- }
-
- assert(n->Opcode == IR_VAR);
-
- if (*direct) {
- const char *var = (const char *) n->Var->a_name;
- GLint pos =
- lookup_statevar(var, index1, index2, field, &swizzle, paramList);
- if (pos >= 0) {
- /* newly resolved storage for the statevar/constant/uniform */
- n0->Store->File = PROGRAM_STATE_VAR;
- n0->Store->Index = pos;
- n0->Store->Swizzle = swizzle;
- n0->Store->Parent = NULL;
- return pos;
- }
- }
-
- *direct = GL_FALSE;
- return alloc_state_var_array(n->Var, paramList);
-}
-
-
-
-
-#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
-
-
-/** Predefined shader inputs */
-struct input_info
-{
- const char *Name;
- GLuint Attrib;
- GLenum Type;
- GLuint Swizzle;
- GLboolean Array;
-};
-
-/** Predefined vertex shader inputs/attributes */
-static const struct input_info vertInputs[] = {
- { "gl_Vertex", VERT_ATTRIB_POS, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_Normal", VERT_ATTRIB_NORMAL, GL_FLOAT_VEC3, SWIZZLE_NOOP, GL_FALSE },
- { "gl_Color", VERT_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_FogCoord", VERT_ATTRIB_FOG, GL_FLOAT, SWIZZLE_XXXX, GL_FALSE },
- { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE }
-};
-
-static const struct input_info geomInputs[] = {
- { "gl_PrimitiveIDIn", GEOM_ATTRIB_PRIMITIVE_ID, GL_FLOAT, SWIZZLE_NOOP, GL_FALSE },
- { "gl_FrontColorIn", GEOM_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
- { "gl_BackColorIn", GEOM_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
- { "gl_FrontSecondaryColorIn", GEOM_ATTRIB_SECONDARY_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
- { "gl_BackSecondaryColorIn", GEOM_ATTRIB_SECONDARY_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
- { "gl_TexCoordIn", GEOM_ATTRIB_TEX_COORD, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
- { "gl_FogFragCoordIn", GEOM_ATTRIB_FOG_FRAG_COORD, GL_FLOAT, SWIZZLE_NOOP, GL_TRUE },
- { "gl_PositionIn", GEOM_ATTRIB_POSITION, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
- { "gl_ClipVertexIn", GEOM_ATTRIB_CLIP_VERTEX, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
- { "gl_PointSizeIn", GEOM_ATTRIB_POINT_SIZE, GL_FLOAT, SWIZZLE_NOOP, GL_TRUE }
-};
-
-/** Predefined fragment shader inputs */
-static const struct input_info fragInputs[] = {
- { "gl_FragCoord", FRAG_ATTRIB_WPOS, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_Color", FRAG_ATTRIB_COL0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_SecondaryColor", FRAG_ATTRIB_COL1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_TexCoord", FRAG_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
- { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, GL_FLOAT, SWIZZLE_XXXX, GL_FALSE },
- { "gl_FrontFacing", FRAG_ATTRIB_FACE, GL_FLOAT, SWIZZLE_XXXX, GL_FALSE },
- { "gl_PointCoord", FRAG_ATTRIB_PNTC, GL_FLOAT_VEC2, SWIZZLE_XYZW, GL_FALSE }
-};
-
-
-/**
- * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
- * a vertex or fragment program input variable. Return -1 if the input
- * name is invalid.
- * XXX return size too
- */
-GLint
-_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut,
- GLboolean *is_array)
-{
- const struct input_info *inputs;
- GLuint i, n;
-
- switch (target) {
- case GL_VERTEX_PROGRAM_ARB:
- inputs = vertInputs;
- n = Elements(vertInputs);
- break;
- case GL_FRAGMENT_PROGRAM_ARB:
- inputs = fragInputs;
- n = Elements(fragInputs);
- break;
- case MESA_GEOMETRY_PROGRAM:
- inputs = geomInputs;
- n = Elements(geomInputs);
- break;
- default:
- _mesa_problem(NULL, "bad target in _slang_input_index");
- return -1;
- }
-
- ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */
-
- for (i = 0; i < n; i++) {
- if (strcmp(inputs[i].Name, name) == 0) {
- /* found */
- *swizzleOut = inputs[i].Swizzle;
- if (is_array)
- *is_array = inputs[i].Array;
- return inputs[i].Attrib;
- }
- }
- return -1;
-}
-
-
-/**
- * Return name of the given vertex attribute (VERT_ATTRIB_x).
- */
-const char *
-_slang_vert_attrib_name(GLuint attrib)
-{
- GLuint i;
- assert(attrib < VERT_ATTRIB_GENERIC0);
- for (i = 0; Elements(vertInputs); i++) {
- if (vertInputs[i].Attrib == attrib)
- return vertInputs[i].Name;
- }
- return NULL;
-}
-
-
-/**
- * Return type (GL_FLOAT, GL_FLOAT_VEC2, etc) of the given vertex
- * attribute (VERT_ATTRIB_x).
- */
-GLenum
-_slang_vert_attrib_type(GLuint attrib)
-{
- GLuint i;
- assert(attrib < VERT_ATTRIB_GENERIC0);
- for (i = 0; Elements(vertInputs); i++) {
- if (vertInputs[i].Attrib == attrib)
- return vertInputs[i].Type;
- }
- return GL_NONE;
-}
-
-
-
-
-
-/** Predefined shader output info */
-struct output_info
-{
- const char *Name;
- GLuint Attrib;
- GLenum Type;
-};
-
-/** Predefined vertex shader outputs */
-static const struct output_info vertOutputs[] = {
- { "gl_Position", VERT_RESULT_HPOS, GL_FLOAT_VEC4 },
- { "gl_FrontColor", VERT_RESULT_COL0, GL_FLOAT_VEC4 },
- { "gl_BackColor", VERT_RESULT_BFC0, GL_FLOAT_VEC4 },
- { "gl_FrontSecondaryColor", VERT_RESULT_COL1, GL_FLOAT_VEC4 },
- { "gl_BackSecondaryColor", VERT_RESULT_BFC1, GL_FLOAT_VEC4 },
- { "gl_TexCoord", VERT_RESULT_TEX0, GL_FLOAT_VEC4 },
- { "gl_FogFragCoord", VERT_RESULT_FOGC, GL_FLOAT },
- { "gl_PointSize", VERT_RESULT_PSIZ, GL_FLOAT }
-};
-
-/** Predefined geometry shader outputs */
-static const struct output_info geomOutputs[] = {
- { "gl_Position", GEOM_RESULT_POS, GL_FLOAT_VEC4 },
- { "gl_FrontColor", GEOM_RESULT_COL0, GL_FLOAT_VEC4 },
- { "gl_BackColor", GEOM_RESULT_COL1, GL_FLOAT_VEC4 },
- { "gl_FrontSecondaryColor", GEOM_RESULT_SCOL0, GL_FLOAT_VEC4 },
- { "gl_BackSecondaryColor", GEOM_RESULT_SCOL1, GL_FLOAT_VEC4 },
- { "gl_TexCoord", GEOM_RESULT_TEX0, GL_FLOAT_VEC4 },
- { "gl_FogFragCoord", GEOM_RESULT_FOGC, GL_FLOAT },
- { "gl_ClipVertex", GEOM_RESULT_CLPV, GL_FLOAT_VEC4 },
- { "gl_PointSize", GEOM_RESULT_PSIZ, GL_FLOAT },
- { "gl_PrimitiveID", GEOM_RESULT_PRID, GL_FLOAT },
- { "gl_Layer", GEOM_RESULT_LAYR, GL_FLOAT }
-};
-
-/** Predefined fragment shader outputs */
-static const struct output_info fragOutputs[] = {
- { "gl_FragColor", FRAG_RESULT_COLOR, GL_FLOAT_VEC4 },
- { "gl_FragDepth", FRAG_RESULT_DEPTH, GL_FLOAT },
- { "gl_FragData", FRAG_RESULT_DATA0, GL_FLOAT_VEC4 }
-};
-
-
-/**
- * Return the VERT_RESULT_*, GEOM_RESULT_* or FRAG_RESULT_* value that corresponds
- * to a vertex or fragment program output variable. Return -1 for an invalid
- * output name.
- */
-GLint
-_slang_output_index(const char *name, GLenum target)
-{
- const struct output_info *outputs;
- GLuint i, n;
-
- switch (target) {
- case GL_VERTEX_PROGRAM_ARB:
- outputs = vertOutputs;
- n = Elements(vertOutputs);
- break;
- case GL_FRAGMENT_PROGRAM_ARB:
- outputs = fragOutputs;
- n = Elements(fragOutputs);
- break;
- case MESA_GEOMETRY_PROGRAM:
- outputs = geomOutputs;
- n = Elements(geomOutputs);
- break;
- default:
- _mesa_problem(NULL, "bad target in _slang_output_index");
- return -1;
- }
-
- for (i = 0; i < n; i++) {
- if (strcmp(outputs[i].Name, name) == 0) {
- /* found */
- return outputs[i].Attrib;
- }
- }
- return -1;
-}
-
-
-/**
- * Given a VERT_RESULT_x index, return the corresponding string name.
- */
-const char *
-_slang_vertex_output_name(gl_vert_result index)
-{
- if (index < Elements(vertOutputs))
- return vertOutputs[index].Name;
- else
- return NULL;
-}
-
-
-/**
- * Given a GEOM_RESULT_x index, return the corresponding string name.
- */
-const char *
-_slang_geometry_output_name(gl_geom_result index)
-{
- if (index < Elements(geomOutputs))
- return geomOutputs[index].Name;
- else
- return NULL;
-}
-
-
-/**
- * Given a FRAG_RESULT_x index, return the corresponding string name.
- */
-const char *
-_slang_fragment_output_name(gl_frag_result index)
-{
- if (index < Elements(fragOutputs))
- return fragOutputs[index].Name;
- else
- return NULL;
-}
-
-
-/**
- * Given a VERT_RESULT_x index, return the corresponding varying
- * var's datatype.
- */
-GLenum
-_slang_vertex_output_type(gl_vert_result index)
-{
- if (index < Elements(vertOutputs))
- return vertOutputs[index].Type;
- else
- return GL_NONE;
-}
diff --git a/src/mesa/slang/slang_builtin.h b/src/mesa/slang/slang_builtin.h
deleted file mode 100644
index dc92f83f8ef..00000000000
--- a/src/mesa/slang/slang_builtin.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-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 SLANG_BUILTIN_H
-#define SLANG_BUILTIN_H
-
-#include "main/glheader.h"
-#include "main/mtypes.h"
-#include "slang_ir.h"
-
-
-extern GLint
-_slang_alloc_statevar(slang_ir_node *n,
- struct gl_program_parameter_list *paramList,
- GLboolean *direct);
-
-
-extern GLint
-_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut,
- GLboolean *is_array);
-
-extern GLint
-_slang_output_index(const char *name, GLenum target);
-
-
-extern const char *
-_slang_vert_attrib_name(GLuint attrib);
-
-extern GLenum
-_slang_vert_attrib_type(GLuint attrib);
-
-
-const char *
-_slang_vertex_output_name(gl_vert_result index);
-
-const char *
-_slang_fragment_output_name(gl_frag_result index);
-
-const char *
-_slang_geometry_output_name(gl_geom_result index);
-
-GLenum
-_slang_vertex_output_type(gl_vert_result index);
-
-
-#endif /* SLANG_BUILTIN_H */
diff --git a/src/mesa/slang/slang_codegen.c b/src/mesa/slang/slang_codegen.c
deleted file mode 100644
index 95787e4409b..00000000000
--- a/src/mesa/slang/slang_codegen.c
+++ /dev/null
@@ -1,5410 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
- * Copyright (C) 2008 VMware, 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.
- */
-
-/**
- * \file slang_codegen.c
- * Generate IR tree from AST.
- * \author Brian Paul
- */
-
-
-/***
- *** NOTES:
- *** The new_() functions return a new instance of a simple IR node.
- *** The gen_() functions generate larger IR trees from the simple nodes.
- ***/
-
-
-
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-#include "program/program.h"
-#include "program/prog_instruction.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-#include "program/prog_statevars.h"
-#include "slang_typeinfo.h"
-#include "slang_builtin.h"
-#include "slang_codegen.h"
-#include "slang_compile.h"
-#include "slang_label.h"
-#include "slang_mem.h"
-#include "slang_simplify.h"
-#include "slang_emit.h"
-#include "slang_vartable.h"
-#include "slang_ir.h"
-#include "slang_print.h"
-
-
-/** Max iterations to unroll */
-const GLuint MAX_FOR_LOOP_UNROLL_ITERATIONS = 32;
-
-/** Max for-loop body size (in slang operations) to unroll */
-const GLuint MAX_FOR_LOOP_UNROLL_BODY_SIZE = 50;
-
-/** Max for-loop body complexity to unroll.
- * We'll compute complexity as the product of the number of iterations
- * and the size of the body. So long-ish loops with very simple bodies
- * can be unrolled, as well as short loops with larger bodies.
- */
-const GLuint MAX_FOR_LOOP_UNROLL_COMPLEXITY = 256;
-
-
-
-static slang_ir_node *
-_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper);
-
-static void
-slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
- GLuint substCount, slang_variable **substOld,
- slang_operation **substNew, GLboolean isLHS);
-
-
-/**
- * Retrieves type information about an operation.
- * Returns GL_TRUE on success.
- * Returns GL_FALSE otherwise.
- */
-static GLboolean
-typeof_operation(const struct slang_assemble_ctx_ *A,
- slang_operation *op,
- slang_typeinfo *ti)
-{
- return _slang_typeof_operation(op, &A->space, ti, A->atoms, A->log);
-}
-
-
-static GLboolean
-is_sampler_type(const slang_fully_specified_type *t)
-{
- switch (t->specifier.type) {
- case SLANG_SPEC_SAMPLER_1D:
- case SLANG_SPEC_SAMPLER_2D:
- case SLANG_SPEC_SAMPLER_3D:
- case SLANG_SPEC_SAMPLER_CUBE:
- case SLANG_SPEC_SAMPLER_1D_SHADOW:
- case SLANG_SPEC_SAMPLER_2D_SHADOW:
- case SLANG_SPEC_SAMPLER_RECT:
- case SLANG_SPEC_SAMPLER_RECT_SHADOW:
- case SLANG_SPEC_SAMPLER_1D_ARRAY:
- case SLANG_SPEC_SAMPLER_2D_ARRAY:
- case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
- case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Return the offset (in floats or ints) of the named field within
- * the given struct. Return -1 if field not found.
- * If field is NULL, return the size of the struct instead.
- */
-static GLint
-_slang_field_offset(const slang_type_specifier *spec, slang_atom field)
-{
- GLint offset = 0;
- GLuint i;
- for (i = 0; i < spec->_struct->fields->num_variables; i++) {
- const slang_variable *v = spec->_struct->fields->variables[i];
- const GLuint sz = _slang_sizeof_type_specifier(&v->type.specifier);
- if (sz > 1) {
- /* types larger than 1 float are register (4-float) aligned */
- offset = (offset + 3) & ~3;
- }
- if (field && v->a_name == field) {
- return offset;
- }
- offset += sz;
- }
- if (field)
- return -1; /* field not found */
- else
- return offset; /* struct size */
-}
-
-
-/**
- * Return the size (in floats) of the given type specifier.
- * If the size is greater than 4, the size should be a multiple of 4
- * so that the correct number of 4-float registers are allocated.
- * For example, a mat3x2 is size 12 because we want to store the
- * 3 columns in 3 float[4] registers.
- */
-GLuint
-_slang_sizeof_type_specifier(const slang_type_specifier *spec)
-{
- GLuint sz;
- switch (spec->type) {
- case SLANG_SPEC_VOID:
- sz = 0;
- break;
- case SLANG_SPEC_BOOL:
- sz = 1;
- break;
- case SLANG_SPEC_BVEC2:
- sz = 2;
- break;
- case SLANG_SPEC_BVEC3:
- sz = 3;
- break;
- case SLANG_SPEC_BVEC4:
- sz = 4;
- break;
- case SLANG_SPEC_INT:
- sz = 1;
- break;
- case SLANG_SPEC_IVEC2:
- sz = 2;
- break;
- case SLANG_SPEC_IVEC3:
- sz = 3;
- break;
- case SLANG_SPEC_IVEC4:
- sz = 4;
- break;
- case SLANG_SPEC_FLOAT:
- sz = 1;
- break;
- case SLANG_SPEC_VEC2:
- sz = 2;
- break;
- case SLANG_SPEC_VEC3:
- sz = 3;
- break;
- case SLANG_SPEC_VEC4:
- sz = 4;
- break;
- case SLANG_SPEC_MAT2:
- sz = 2 * 4; /* 2 columns (regs) */
- break;
- case SLANG_SPEC_MAT3:
- sz = 3 * 4;
- break;
- case SLANG_SPEC_MAT4:
- sz = 4 * 4;
- break;
- case SLANG_SPEC_MAT23:
- sz = 2 * 4; /* 2 columns (regs) */
- break;
- case SLANG_SPEC_MAT32:
- sz = 3 * 4; /* 3 columns (regs) */
- break;
- case SLANG_SPEC_MAT24:
- sz = 2 * 4;
- break;
- case SLANG_SPEC_MAT42:
- sz = 4 * 4; /* 4 columns (regs) */
- break;
- case SLANG_SPEC_MAT34:
- sz = 3 * 4;
- break;
- case SLANG_SPEC_MAT43:
- sz = 4 * 4; /* 4 columns (regs) */
- break;
- case SLANG_SPEC_SAMPLER_1D:
- case SLANG_SPEC_SAMPLER_2D:
- case SLANG_SPEC_SAMPLER_3D:
- case SLANG_SPEC_SAMPLER_CUBE:
- case SLANG_SPEC_SAMPLER_1D_SHADOW:
- case SLANG_SPEC_SAMPLER_2D_SHADOW:
- case SLANG_SPEC_SAMPLER_RECT:
- case SLANG_SPEC_SAMPLER_RECT_SHADOW:
- case SLANG_SPEC_SAMPLER_1D_ARRAY:
- case SLANG_SPEC_SAMPLER_2D_ARRAY:
- case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
- case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
- sz = 1; /* a sampler is basically just an integer index */
- break;
- case SLANG_SPEC_STRUCT:
- sz = _slang_field_offset(spec, 0); /* special use */
- if (sz == 1) {
- /* 1-float structs are actually troublesome to deal with since they
- * might get placed at R.x, R.y, R.z or R.z. Return size=2 to
- * ensure the object is placed at R.x
- */
- sz = 2;
- }
- else if (sz > 4) {
- sz = (sz + 3) & ~0x3; /* round up to multiple of four */
- }
- break;
- case SLANG_SPEC_ARRAY:
- sz = _slang_sizeof_type_specifier(spec->_array);
- break;
- default:
- _mesa_problem(NULL, "Unexpected type in _slang_sizeof_type_specifier()");
- sz = 0;
- }
-
- if (sz > 4) {
- /* if size is > 4, it should be a multiple of four */
- assert((sz & 0x3) == 0);
- }
- return sz;
-}
-
-
-/**
- * Query variable/array length (number of elements).
- * This is slightly non-trivial because there are two ways to express
- * arrays: "float x[3]" vs. "float[3] x".
- * \return the length of the array for the given variable, or 0 if not an array
- */
-static GLint
-_slang_array_length(const slang_variable *var)
-{
- if (var->type.array_len > 0) {
- /* Ex: float[4] x; */
- return var->type.array_len;
- }
- if (var->array_len > 0) {
- /* Ex: float x[4]; */
- return var->array_len;
- }
- return 0;
-}
-
-
-/**
- * Compute total size of array give size of element, number of elements.
- * \return size in floats
- */
-static GLint
-_slang_array_size(GLint elemSize, GLint arrayLen)
-{
- GLint total;
- assert(elemSize > 0);
- if (arrayLen > 1) {
- /* round up base type to multiple of 4 */
- total = ((elemSize + 3) & ~0x3) * MAX2(arrayLen, 1);
- }
- else {
- total = elemSize;
- }
- return total;
-}
-
-
-/**
- * Return the TEXTURE_*_INDEX value that corresponds to a sampler type,
- * or -1 if the type is not a sampler.
- */
-static GLint
-sampler_to_texture_index(const slang_type_specifier_type type)
-{
- switch (type) {
- case SLANG_SPEC_SAMPLER_1D:
- return TEXTURE_1D_INDEX;
- case SLANG_SPEC_SAMPLER_2D:
- return TEXTURE_2D_INDEX;
- case SLANG_SPEC_SAMPLER_3D:
- return TEXTURE_3D_INDEX;
- case SLANG_SPEC_SAMPLER_CUBE:
- return TEXTURE_CUBE_INDEX;
- case SLANG_SPEC_SAMPLER_1D_SHADOW:
- return TEXTURE_1D_INDEX; /* XXX fix */
- case SLANG_SPEC_SAMPLER_2D_SHADOW:
- return TEXTURE_2D_INDEX; /* XXX fix */
- case SLANG_SPEC_SAMPLER_RECT:
- return TEXTURE_RECT_INDEX;
- case SLANG_SPEC_SAMPLER_RECT_SHADOW:
- return TEXTURE_RECT_INDEX; /* XXX fix */
- case SLANG_SPEC_SAMPLER_1D_ARRAY:
- return TEXTURE_1D_ARRAY_INDEX;
- case SLANG_SPEC_SAMPLER_2D_ARRAY:
- return TEXTURE_2D_ARRAY_INDEX;
- case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
- return TEXTURE_1D_ARRAY_INDEX;
- case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
- return TEXTURE_2D_ARRAY_INDEX;
- default:
- return -1;
- }
-}
-
-
-/** helper to build a SLANG_OPER_IDENTIFIER node */
-static void
-slang_operation_identifier(slang_operation *oper,
- slang_assemble_ctx *A,
- const char *name)
-{
- oper->type = SLANG_OPER_IDENTIFIER;
- oper->a_id = slang_atom_pool_atom(A->atoms, name);
-}
-
-
-/**
- * Called when we begin code/IR generation for a new while/do/for loop.
- */
-static void
-push_loop(slang_assemble_ctx *A, slang_operation *loopOper, slang_ir_node *loopIR)
-{
- A->LoopOperStack[A->LoopDepth] = loopOper;
- A->LoopIRStack[A->LoopDepth] = loopIR;
- A->LoopDepth++;
-}
-
-
-/**
- * Called when we end code/IR generation for a new while/do/for loop.
- */
-static void
-pop_loop(slang_assemble_ctx *A)
-{
- assert(A->LoopDepth > 0);
- A->LoopDepth--;
-}
-
-
-/**
- * Return pointer to slang_operation for the loop we're currently inside,
- * or NULL if not in a loop.
- */
-static const slang_operation *
-current_loop_oper(const slang_assemble_ctx *A)
-{
- if (A->LoopDepth > 0)
- return A->LoopOperStack[A->LoopDepth - 1];
- else
- return NULL;
-}
-
-
-/**
- * Return pointer to slang_ir_node for the loop we're currently inside,
- * or NULL if not in a loop.
- */
-static slang_ir_node *
-current_loop_ir(const slang_assemble_ctx *A)
-{
- if (A->LoopDepth > 0)
- return A->LoopIRStack[A->LoopDepth - 1];
- else
- return NULL;
-}
-
-
-/**********************************************************************/
-
-
-/**
- * Map "_asm foo" to IR_FOO, etc.
- */
-typedef struct
-{
- const char *Name;
- slang_ir_opcode Opcode;
- GLuint HaveRetValue, NumParams;
-} slang_asm_info;
-
-
-static slang_asm_info AsmInfo[] = {
- /* vec4 binary op */
- { "vec4_add", IR_ADD, 1, 2 },
- { "vec4_subtract", IR_SUB, 1, 2 },
- { "vec4_multiply", IR_MUL, 1, 2 },
- { "vec4_dot", IR_DOT4, 1, 2 },
- { "vec3_dot", IR_DOT3, 1, 2 },
- { "vec2_dot", IR_DOT2, 1, 2 },
- { "vec3_nrm", IR_NRM3, 1, 1 },
- { "vec4_nrm", IR_NRM4, 1, 1 },
- { "vec3_cross", IR_CROSS, 1, 2 },
- { "vec4_lrp", IR_LRP, 1, 3 },
- { "vec4_min", IR_MIN, 1, 2 },
- { "vec4_max", IR_MAX, 1, 2 },
- { "vec4_cmp", IR_CMP, 1, 3 },
- { "vec4_clamp", IR_CLAMP, 1, 3 },
- { "vec4_seq", IR_SEQUAL, 1, 2 },
- { "vec4_sne", IR_SNEQUAL, 1, 2 },
- { "vec4_sge", IR_SGE, 1, 2 },
- { "vec4_sgt", IR_SGT, 1, 2 },
- { "vec4_sle", IR_SLE, 1, 2 },
- { "vec4_slt", IR_SLT, 1, 2 },
- /* vec4 unary */
- { "vec4_move", IR_MOVE, 1, 1 },
- { "vec4_floor", IR_FLOOR, 1, 1 },
- { "vec4_frac", IR_FRAC, 1, 1 },
- { "vec4_abs", IR_ABS, 1, 1 },
- { "vec4_negate", IR_NEG, 1, 1 },
- { "vec4_ddx", IR_DDX, 1, 1 },
- { "vec4_ddy", IR_DDY, 1, 1 },
- /* float binary op */
- { "float_power", IR_POW, 1, 2 },
- /* texture / sampler */
- { "vec4_tex_1d", IR_TEX, 1, 2 },
- { "vec4_tex_1d_bias", IR_TEXB, 1, 2 }, /* 1d w/ bias */
- { "vec4_tex_1d_proj", IR_TEXP, 1, 2 }, /* 1d w/ projection */
- { "vec4_tex_2d", IR_TEX, 1, 2 },
- { "vec4_tex_2d_bias", IR_TEXB, 1, 2 }, /* 2d w/ bias */
- { "vec4_tex_2d_proj", IR_TEXP, 1, 2 }, /* 2d w/ projection */
- { "vec4_tex_3d", IR_TEX, 1, 2 },
- { "vec4_tex_3d_bias", IR_TEXB, 1, 2 }, /* 3d w/ bias */
- { "vec4_tex_3d_proj", IR_TEXP, 1, 2 }, /* 3d w/ projection */
- { "vec4_tex_cube", IR_TEX, 1, 2 }, /* cubemap */
- { "vec4_tex_rect", IR_TEX, 1, 2 }, /* rectangle */
- { "vec4_tex_rect_bias", IR_TEX, 1, 2 }, /* rectangle w/ projection */
- { "vec4_tex_1d_array", IR_TEX, 1, 2 },
- { "vec4_tex_1d_array_bias", IR_TEXB, 1, 2 },
- { "vec4_tex_1d_array_shadow", IR_TEX, 1, 2 },
- { "vec4_tex_1d_array_bias_shadow", IR_TEXB, 1, 2 },
- { "vec4_tex_2d_array", IR_TEX, 1, 2 },
- { "vec4_tex_2d_array_bias", IR_TEXB, 1, 2 },
- { "vec4_tex_2d_array_shadow", IR_TEX, 1, 2 },
- { "vec4_tex_2d_array_bias_shadow", IR_TEXB, 1, 2 },
-
- /* texture / sampler but with shadow comparison */
- { "vec4_tex_1d_shadow", IR_TEX_SH, 1, 2 },
- { "vec4_tex_1d_bias_shadow", IR_TEXB_SH, 1, 2 },
- { "vec4_tex_1d_proj_shadow", IR_TEXP_SH, 1, 2 },
- { "vec4_tex_2d_shadow", IR_TEX_SH, 1, 2 },
- { "vec4_tex_2d_bias_shadow", IR_TEXB_SH, 1, 2 },
- { "vec4_tex_2d_proj_shadow", IR_TEXP_SH, 1, 2 },
- { "vec4_tex_rect_shadow", IR_TEX_SH, 1, 2 },
- { "vec4_tex_rect_proj_shadow", IR_TEXP_SH, 1, 2 },
-
- /* unary op */
- { "ivec4_to_vec4", IR_I_TO_F, 1, 1 }, /* int[4] to float[4] */
- { "vec4_to_ivec4", IR_F_TO_I, 1, 1 }, /* float[4] to int[4] */
- { "float_exp", IR_EXP, 1, 1 },
- { "float_exp2", IR_EXP2, 1, 1 },
- { "float_log2", IR_LOG2, 1, 1 },
- { "float_rsq", IR_RSQ, 1, 1 },
- { "float_rcp", IR_RCP, 1, 1 },
- { "float_sine", IR_SIN, 1, 1 },
- { "float_cosine", IR_COS, 1, 1 },
- { "float_noise1", IR_NOISE1, 1, 1},
- { "float_noise2", IR_NOISE2, 1, 1},
- { "float_noise3", IR_NOISE3, 1, 1},
- { "float_noise4", IR_NOISE4, 1, 1},
-
- { "emit_vertex", IR_EMIT_VERTEX, 0, 0},
- { "end_primitive", IR_END_PRIMITIVE, 0, 0},
-
- { NULL, IR_NOP, 0, 0 }
-};
-
-
-static slang_ir_node *
-new_node3(slang_ir_opcode op,
- slang_ir_node *c0, slang_ir_node *c1, slang_ir_node *c2)
-{
- slang_ir_node *n = (slang_ir_node *) _slang_alloc(sizeof(slang_ir_node));
- if (n) {
- n->Opcode = op;
- n->Children[0] = c0;
- n->Children[1] = c1;
- n->Children[2] = c2;
- n->InstLocation = -1;
- }
- return n;
-}
-
-static slang_ir_node *
-new_node2(slang_ir_opcode op, slang_ir_node *c0, slang_ir_node *c1)
-{
- return new_node3(op, c0, c1, NULL);
-}
-
-static slang_ir_node *
-new_node1(slang_ir_opcode op, slang_ir_node *c0)
-{
- return new_node3(op, c0, NULL, NULL);
-}
-
-static slang_ir_node *
-new_node0(slang_ir_opcode op)
-{
- return new_node3(op, NULL, NULL, NULL);
-}
-
-
-/**
- * Create sequence of two nodes.
- */
-static slang_ir_node *
-new_seq(slang_ir_node *left, slang_ir_node *right)
-{
- if (!left)
- return right;
- if (!right)
- return left;
- return new_node2(IR_SEQ, left, right);
-}
-
-static slang_ir_node *
-new_label(slang_label *label)
-{
- slang_ir_node *n = new_node0(IR_LABEL);
- assert(label);
- if (n)
- n->Label = label;
- return n;
-}
-
-static slang_ir_node *
-new_float_literal(const float v[4], GLuint size)
-{
- slang_ir_node *n = new_node0(IR_FLOAT);
- assert(size <= 4);
- COPY_4V(n->Value, v);
- /* allocate a storage object, but compute actual location (Index) later */
- n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
- return n;
-}
-
-
-static slang_ir_node *
-new_not(slang_ir_node *n)
-{
- return new_node1(IR_NOT, n);
-}
-
-
-/**
- * Non-inlined function call.
- */
-static slang_ir_node *
-new_function_call(slang_ir_node *code, slang_label *name)
-{
- slang_ir_node *n = new_node1(IR_CALL, code);
- assert(name);
- if (n)
- n->Label = name;
- return n;
-}
-
-
-/**
- * Unconditional jump.
- */
-static slang_ir_node *
-new_return(slang_label *dest)
-{
- slang_ir_node *n = new_node0(IR_RETURN);
- assert(dest);
- if (n)
- n->Label = dest;
- return n;
-}
-
-
-static slang_ir_node *
-new_loop(slang_ir_node *body)
-{
- return new_node1(IR_LOOP, body);
-}
-
-
-static slang_ir_node *
-new_break(slang_ir_node *loopNode)
-{
- slang_ir_node *n = new_node0(IR_BREAK);
- assert(loopNode);
- assert(loopNode->Opcode == IR_LOOP);
- if (n) {
- /* insert this node at head of linked list of cont/break instructions */
- n->List = loopNode->List;
- loopNode->List = n;
- }
- return n;
-}
-
-
-/**
- * Make new IR_BREAK_IF_TRUE.
- */
-static slang_ir_node *
-new_break_if_true(slang_assemble_ctx *A, slang_ir_node *cond)
-{
- slang_ir_node *loopNode = current_loop_ir(A);
- slang_ir_node *n;
- assert(loopNode);
- assert(loopNode->Opcode == IR_LOOP);
- n = new_node1(IR_BREAK_IF_TRUE, cond);
- if (n) {
- /* insert this node at head of linked list of cont/break instructions */
- n->List = loopNode->List;
- loopNode->List = n;
- }
- return n;
-}
-
-
-/**
- * Make new IR_CONT_IF_TRUE node.
- */
-static slang_ir_node *
-new_cont_if_true(slang_assemble_ctx *A, slang_ir_node *cond)
-{
- slang_ir_node *loopNode = current_loop_ir(A);
- slang_ir_node *n;
- assert(loopNode);
- assert(loopNode->Opcode == IR_LOOP);
- n = new_node1(IR_CONT_IF_TRUE, cond);
- if (n) {
- n->Parent = loopNode; /* pointer to containing loop */
- /* insert this node at head of linked list of cont/break instructions */
- n->List = loopNode->List;
- loopNode->List = n;
- }
- return n;
-}
-
-
-static slang_ir_node *
-new_cond(slang_ir_node *n)
-{
- slang_ir_node *c = new_node1(IR_COND, n);
- return c;
-}
-
-
-static slang_ir_node *
-new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart)
-{
- return new_node3(IR_IF, cond, ifPart, elsePart);
-}
-
-
-/**
- * New IR_VAR node - a reference to a previously declared variable.
- */
-static slang_ir_node *
-new_var(slang_assemble_ctx *A, slang_variable *var)
-{
- slang_ir_node *n = new_node0(IR_VAR);
- if (n) {
- ASSERT(var);
- ASSERT(var->store);
- ASSERT(!n->Store);
- ASSERT(!n->Var);
-
- /* Set IR node's Var and Store pointers */
- n->Var = var;
- n->Store = var->store;
- }
- return n;
-}
-
-
-/**
- * Check if the given function is really just a wrapper for a
- * basic assembly instruction.
- */
-static GLboolean
-slang_is_asm_function(const slang_function *fun)
-{
- if (fun->body->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE &&
- fun->body->num_children == 1 &&
- fun->body->children[0].type == SLANG_OPER_ASM) {
- return GL_TRUE;
- }
- return GL_FALSE;
-}
-
-
-static GLboolean
-_slang_is_noop(const slang_operation *oper)
-{
- if (!oper ||
- oper->type == SLANG_OPER_VOID ||
- (oper->num_children == 1 && oper->children[0].type == SLANG_OPER_VOID))
- return GL_TRUE;
- else
- return GL_FALSE;
-}
-
-
-/**
- * Recursively search tree for a node of the given type.
- */
-#if 0
-static slang_operation *
-_slang_find_node_type(slang_operation *oper, slang_operation_type type)
-{
- GLuint i;
- if (oper->type == type)
- return oper;
- for (i = 0; i < oper->num_children; i++) {
- slang_operation *p = _slang_find_node_type(&oper->children[i], type);
- if (p)
- return p;
- }
- return NULL;
-}
-#endif
-
-
-/**
- * Count the number of operations of the given time rooted at 'oper'.
- */
-static GLuint
-_slang_count_node_type(const slang_operation *oper, slang_operation_type type)
-{
- GLuint i, count = 0;
- if (oper->type == type) {
- return 1;
- }
- for (i = 0; i < oper->num_children; i++) {
- count += _slang_count_node_type(&oper->children[i], type);
- }
- return count;
-}
-
-
-/**
- * Check if the 'return' statement found under 'oper' is a "tail return"
- * that can be no-op'd. For example:
- *
- * void func(void)
- * {
- * .. do something ..
- * return; // this is a no-op
- * }
- *
- * This is used when determining if a function can be inlined. If the
- * 'return' is not the last statement, we can't inline the function since
- * we still need the semantic behaviour of the 'return' but we don't want
- * to accidentally return from the _calling_ function. We'd need to use an
- * unconditional branch, but we don't have such a GPU instruction (not
- * always, at least).
- */
-static GLboolean
-_slang_is_tail_return(const slang_operation *oper)
-{
- GLuint k = oper->num_children;
-
- while (k > 0) {
- const slang_operation *last = &oper->children[k - 1];
- if (last->type == SLANG_OPER_RETURN)
- return GL_TRUE;
- else if (last->type == SLANG_OPER_IDENTIFIER ||
- last->type == SLANG_OPER_LABEL)
- k--; /* try prev child */
- else if (last->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE ||
- last->type == SLANG_OPER_BLOCK_NEW_SCOPE)
- /* try sub-children */
- return _slang_is_tail_return(last);
- else
- break;
- }
-
- return GL_FALSE;
-}
-
-
-/**
- * Generate a variable declaration opeartion.
- * I.e.: generate AST code for "bool flag = false;"
- */
-static void
-slang_generate_declaration(slang_assemble_ctx *A,
- slang_variable_scope *scope,
- slang_operation *decl,
- slang_type_specifier_type type,
- const char *name,
- GLint initValue)
-{
- slang_variable *var;
-
- assert(type == SLANG_SPEC_BOOL ||
- type == SLANG_SPEC_INT);
-
- decl->type = SLANG_OPER_VARIABLE_DECL;
-
- var = slang_variable_scope_grow(scope);
-
- slang_fully_specified_type_construct(&var->type);
-
- var->type.specifier.type = type;
- var->a_name = slang_atom_pool_atom(A->atoms, name);
- decl->a_id = var->a_name;
- var->initializer = slang_operation_new(1);
- slang_operation_literal_bool(var->initializer, initValue);
-}
-
-
-static void
-slang_resolve_variable(slang_operation *oper)
-{
- if (oper->type == SLANG_OPER_IDENTIFIER && !oper->var) {
- oper->var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
- }
-}
-
-
-/**
- * Rewrite AST code for "return expression;".
- *
- * We return values from functions by assinging the returned value to
- * the hidden __retVal variable which is an extra 'out' parameter we add
- * to the function signature.
- * This code basically converts "return expr;" into "__retVal = expr; return;"
- *
- * \return the new AST code.
- */
-static slang_operation *
-gen_return_with_expression(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_operation *blockOper, *assignOper;
-
- assert(oper->type == SLANG_OPER_RETURN);
-
- if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
- slang_info_log_error(A->log, "illegal return expression");
- return NULL;
- }
-
- blockOper = slang_operation_new(1);
- blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
- blockOper->locals->outer_scope = oper->locals->outer_scope;
- slang_operation_add_children(blockOper, 2);
-
- if (A->UseReturnFlag) {
- /* Emit:
- * {
- * if (__notRetFlag)
- * __retVal = expr;
- * __notRetFlag = 0;
- * }
- */
- {
- slang_operation *ifOper = slang_oper_child(blockOper, 0);
- ifOper->type = SLANG_OPER_IF;
- slang_operation_add_children(ifOper, 3);
- {
- slang_operation *cond = slang_oper_child(ifOper, 0);
- cond->type = SLANG_OPER_IDENTIFIER;
- cond->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
- }
- {
- slang_operation *elseOper = slang_oper_child(ifOper, 2);
- elseOper->type = SLANG_OPER_VOID;
- }
- assignOper = slang_oper_child(ifOper, 1);
- }
- {
- slang_operation *setOper = slang_oper_child(blockOper, 1);
- setOper->type = SLANG_OPER_ASSIGN;
- slang_operation_add_children(setOper, 2);
- {
- slang_operation *lhs = slang_oper_child(setOper, 0);
- lhs->type = SLANG_OPER_IDENTIFIER;
- lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
- }
- {
- slang_operation *rhs = slang_oper_child(setOper, 1);
- slang_operation_literal_bool(rhs, GL_FALSE);
- }
- }
- }
- else {
- /* Emit:
- * {
- * __retVal = expr;
- * return_inlined;
- * }
- */
- assignOper = slang_oper_child(blockOper, 0);
- {
- slang_operation *returnOper = slang_oper_child(blockOper, 1);
- returnOper->type = SLANG_OPER_RETURN_INLINED;
- assert(returnOper->num_children == 0);
- }
- }
-
- /* __retVal = expression; */
- assignOper->type = SLANG_OPER_ASSIGN;
- slang_operation_add_children(assignOper, 2);
- {
- slang_operation *lhs = slang_oper_child(assignOper, 0);
- lhs->type = SLANG_OPER_IDENTIFIER;
- lhs->a_id = slang_atom_pool_atom(A->atoms, "__retVal");
- }
- {
- slang_operation *rhs = slang_oper_child(assignOper, 1);
- slang_operation_copy(rhs, &oper->children[0]);
- }
-
- /*blockOper->locals->outer_scope = oper->locals->outer_scope;*/
-
- /*slang_print_tree(blockOper, 0);*/
-
- return blockOper;
-}
-
-
-/**
- * Rewrite AST code for "return;" (no expression).
- */
-static slang_operation *
-gen_return_without_expression(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_operation *newRet;
-
- assert(oper->type == SLANG_OPER_RETURN);
-
- if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
- slang_info_log_error(A->log, "return statement requires an expression");
- return NULL;
- }
-
- if (A->UseReturnFlag) {
- /* Emit:
- * __notRetFlag = 0;
- */
- {
- newRet = slang_operation_new(1);
- newRet->locals->outer_scope = oper->locals->outer_scope;
- newRet->type = SLANG_OPER_ASSIGN;
- slang_operation_add_children(newRet, 2);
- {
- slang_operation *lhs = slang_oper_child(newRet, 0);
- lhs->type = SLANG_OPER_IDENTIFIER;
- lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
- }
- {
- slang_operation *rhs = slang_oper_child(newRet, 1);
- slang_operation_literal_bool(rhs, GL_FALSE);
- }
- }
- }
- else {
- /* Emit:
- * return_inlined;
- */
- newRet = slang_operation_new(1);
- newRet->locals->outer_scope = oper->locals->outer_scope;
- newRet->type = SLANG_OPER_RETURN_INLINED;
- }
-
- /*slang_print_tree(newRet, 0);*/
-
- return newRet;
-}
-
-
-
-
-/**
- * Replace particular variables (SLANG_OPER_IDENTIFIER) with new expressions.
- */
-static void
-slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
- GLuint substCount, slang_variable **substOld,
- slang_operation **substNew, GLboolean isLHS)
-{
- switch (oper->type) {
- case SLANG_OPER_VARIABLE_DECL:
- {
- slang_variable *v = _slang_variable_locate(oper->locals,
- oper->a_id, GL_TRUE);
- assert(v);
- if (v->initializer && oper->num_children == 0) {
- /* set child of oper to copy of initializer */
- oper->num_children = 1;
- oper->children = slang_operation_new(1);
- slang_operation_copy(&oper->children[0], v->initializer);
- }
- if (oper->num_children == 1) {
- /* the initializer */
- slang_substitute(A, &oper->children[0], substCount,
- substOld, substNew, GL_FALSE);
- }
- }
- break;
- case SLANG_OPER_IDENTIFIER:
- assert(oper->num_children == 0);
- if (1/**!isLHS XXX FIX */) {
- slang_atom id = oper->a_id;
- slang_variable *v;
- GLuint i;
- v = _slang_variable_locate(oper->locals, id, GL_TRUE);
- if (!v) {
-#if 0
- if (strcmp((char *) oper->a_id, "__notRetFlag"))
- _mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id);
-#endif
- return;
- }
-
- /* look for a substitution */
- for (i = 0; i < substCount; i++) {
- if (v == substOld[i]) {
- /* OK, replace this SLANG_OPER_IDENTIFIER with a new expr */
-#if 0 /* DEBUG only */
- if (substNew[i]->type == SLANG_OPER_IDENTIFIER) {
- assert(substNew[i]->var);
- assert(substNew[i]->var->a_name);
- printf("Substitute %s with %s in id node %p\n",
- (char*)v->a_name, (char*) substNew[i]->var->a_name,
- (void*) oper);
- }
- else {
- printf("Substitute %s with %f in id node %p\n",
- (char*)v->a_name, substNew[i]->literal[0],
- (void*) oper);
- }
-#endif
- slang_operation_copy(oper, substNew[i]);
- break;
- }
- }
- }
- break;
-
- case SLANG_OPER_RETURN:
- {
- slang_operation *newReturn;
- /* generate new 'return' code' */
- if (slang_oper_child(oper, 0)->type == SLANG_OPER_VOID)
- newReturn = gen_return_without_expression(A, oper);
- else
- newReturn = gen_return_with_expression(A, oper);
-
- if (!newReturn)
- return;
-
- /* do substitutions on the new 'return' code */
- slang_substitute(A, newReturn,
- substCount, substOld, substNew, GL_FALSE);
-
- /* install new 'return' code */
- slang_operation_copy(oper, newReturn);
- slang_operation_destruct(newReturn);
- }
- break;
-
- case SLANG_OPER_ASSIGN:
- case SLANG_OPER_SUBSCRIPT:
- /* special case:
- * child[0] can't have substitutions but child[1] can.
- */
- slang_substitute(A, &oper->children[0],
- substCount, substOld, substNew, GL_TRUE);
- slang_substitute(A, &oper->children[1],
- substCount, substOld, substNew, GL_FALSE);
- break;
- case SLANG_OPER_FIELD:
- /* XXX NEW - test */
- slang_substitute(A, &oper->children[0],
- substCount, substOld, substNew, GL_TRUE);
- break;
- default:
- {
- GLuint i;
- for (i = 0; i < oper->num_children; i++)
- slang_substitute(A, &oper->children[i],
- substCount, substOld, substNew, GL_FALSE);
- }
- }
-}
-
-
-/**
- * Produce inline code for a call to an assembly instruction.
- * This is typically used to compile a call to a built-in function like this:
- *
- * vec4 mix(const vec4 x, const vec4 y, const vec4 a)
- * {
- * __asm vec4_lrp __retVal, a, y, x;
- * }
- *
- *
- * A call to
- * r = mix(p1, p2, p3);
- *
- * Becomes:
- *
- * mov
- * / \
- * r vec4_lrp
- * / | \
- * p3 p2 p1
- *
- * We basically translate a SLANG_OPER_CALL into a SLANG_OPER_ASM.
- */
-static slang_operation *
-slang_inline_asm_function(slang_assemble_ctx *A,
- slang_function *fun, slang_operation *oper)
-{
- const GLuint numArgs = oper->num_children;
- GLuint i;
- slang_operation *inlined;
- const GLboolean haveRetValue = _slang_function_has_return_value(fun);
- slang_variable **substOld;
- slang_operation **substNew;
-
- ASSERT(slang_is_asm_function(fun));
- ASSERT(fun->param_count == numArgs + haveRetValue);
-
- /*
- printf("Inline %s as %s\n",
- (char*) fun->header.a_name,
- (char*) fun->body->children[0].a_id);
- */
-
- /*
- * We'll substitute formal params with actual args in the asm call.
- */
- substOld = (slang_variable **)
- _slang_alloc(numArgs * sizeof(slang_variable *));
- substNew = (slang_operation **)
- _slang_alloc(numArgs * sizeof(slang_operation *));
- for (i = 0; i < numArgs; i++) {
- substOld[i] = fun->parameters->variables[i];
- substNew[i] = oper->children + i;
- }
-
- /* make a copy of the code to inline */
- inlined = slang_operation_new(1);
- slang_operation_copy(inlined, &fun->body->children[0]);
- if (haveRetValue) {
- /* get rid of the __retVal child */
- inlined->num_children--;
- for (i = 0; i < inlined->num_children; i++) {
- inlined->children[i] = inlined->children[i + 1];
- }
- }
-
- /* now do formal->actual substitutions */
- slang_substitute(A, inlined, numArgs, substOld, substNew, GL_FALSE);
-
- _slang_free(substOld);
- _slang_free(substNew);
-
-#if 0
- printf("+++++++++++++ inlined asm function %s +++++++++++++\n",
- (char *) fun->header.a_name);
- slang_print_tree(inlined, 3);
- printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-#endif
-
- return inlined;
-}
-
-
-/**
- * Inline the given function call operation.
- * Return a new slang_operation that corresponds to the inlined code.
- */
-static slang_operation *
-slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
- slang_operation *oper, slang_operation *returnOper)
-{
- typedef enum {
- SUBST = 1,
- COPY_IN,
- COPY_OUT
- } ParamMode;
- ParamMode *paramMode;
- const GLboolean haveRetValue = _slang_function_has_return_value(fun);
- const GLuint numArgs = oper->num_children;
- const GLuint totalArgs = numArgs + haveRetValue;
- slang_operation *args = oper->children;
- slang_operation *inlined, *top;
- slang_variable **substOld;
- slang_operation **substNew;
- GLuint substCount, numCopyIn, i;
- slang_function *prevFunction;
- slang_variable_scope *newScope = NULL;
-
- /* save / push */
- prevFunction = A->CurFunction;
- A->CurFunction = fun;
-
- /*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */
- assert(fun->param_count == totalArgs);
-
- /* allocate temporary arrays */
- paramMode = (ParamMode *)
- _slang_alloc(totalArgs * sizeof(ParamMode));
- substOld = (slang_variable **)
- _slang_alloc(totalArgs * sizeof(slang_variable *));
- substNew = (slang_operation **)
- _slang_alloc(totalArgs * sizeof(slang_operation *));
-
-#if 0
- printf("\nInline call to %s (total vars=%d nparams=%d)\n",
- (char *) fun->header.a_name,
- fun->parameters->num_variables, numArgs);
-#endif
-
- if (haveRetValue && !returnOper) {
- /* Create 3-child comma sequence for inlined code:
- * child[0]: declare __resultTmp
- * child[1]: inlined function body
- * child[2]: __resultTmp
- */
- slang_operation *commaSeq;
- slang_operation *declOper = NULL;
- slang_variable *resultVar;
-
- commaSeq = slang_operation_new(1);
- commaSeq->type = SLANG_OPER_SEQUENCE;
- assert(commaSeq->locals);
- commaSeq->locals->outer_scope = oper->locals->outer_scope;
- commaSeq->num_children = 3;
- commaSeq->children = slang_operation_new(3);
- /* allocate the return var */
- resultVar = slang_variable_scope_grow(commaSeq->locals);
- /*
- printf("Alloc __resultTmp in scope %p for retval of calling %s\n",
- (void*)commaSeq->locals, (char *) fun->header.a_name);
- */
-
- resultVar->a_name = slang_atom_pool_atom(A->atoms, "__resultTmp");
- resultVar->type = fun->header.type; /* XXX copy? */
- resultVar->isTemp = GL_TRUE;
-
- /* child[0] = __resultTmp declaration */
- declOper = &commaSeq->children[0];
- declOper->type = SLANG_OPER_VARIABLE_DECL;
- declOper->a_id = resultVar->a_name;
- declOper->locals->outer_scope = commaSeq->locals;
-
- /* child[1] = function body */
- inlined = &commaSeq->children[1];
- inlined->locals->outer_scope = commaSeq->locals;
-
- /* child[2] = __resultTmp reference */
- returnOper = &commaSeq->children[2];
- returnOper->type = SLANG_OPER_IDENTIFIER;
- returnOper->a_id = resultVar->a_name;
- returnOper->locals->outer_scope = commaSeq->locals;
-
- top = commaSeq;
- }
- else {
- top = inlined = slang_operation_new(1);
- /* XXXX this may be inappropriate!!!! */
- inlined->locals->outer_scope = oper->locals->outer_scope;
- }
-
-
- assert(inlined->locals);
-
- /* Examine the parameters, look for inout/out params, look for possible
- * substitutions, etc:
- * param type behaviour
- * in copy actual to local
- * const in substitute param with actual
- * out copy out
- */
- substCount = 0;
- for (i = 0; i < totalArgs; i++) {
- slang_variable *p = fun->parameters->variables[i];
- /*
- printf("Param %d: %s %s \n", i,
- slang_type_qual_string(p->type.qualifier),
- (char *) p->a_name);
- */
- if (p->type.qualifier == SLANG_QUAL_INOUT ||
- p->type.qualifier == SLANG_QUAL_OUT) {
- /* an output param */
- slang_operation *arg;
- if (i < numArgs)
- arg = &args[i];
- else
- arg = returnOper;
- paramMode[i] = SUBST;
-
- if (arg->type == SLANG_OPER_IDENTIFIER)
- slang_resolve_variable(arg);
-
- /* replace parameter 'p' with argument 'arg' */
- substOld[substCount] = p;
- substNew[substCount] = arg; /* will get copied */
- substCount++;
- }
- else if (p->type.qualifier == SLANG_QUAL_CONST) {
- /* a constant input param */
- if (args[i].type == SLANG_OPER_IDENTIFIER ||
- args[i].type == SLANG_OPER_LITERAL_FLOAT ||
- args[i].type == SLANG_OPER_SUBSCRIPT) {
- /* replace all occurances of this parameter variable with the
- * actual argument variable or a literal.
- */
- paramMode[i] = SUBST;
- slang_resolve_variable(&args[i]);
- substOld[substCount] = p;
- substNew[substCount] = &args[i]; /* will get copied */
- substCount++;
- }
- else {
- paramMode[i] = COPY_IN;
- }
- }
- else {
- paramMode[i] = COPY_IN;
- }
- assert(paramMode[i]);
- }
-
- /* actual code inlining: */
- slang_operation_copy(inlined, fun->body);
-
- /*** XXX review this */
- assert(inlined->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE ||
- inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE);
- inlined->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-
-#if 0
- printf("======================= orig body code ======================\n");
- printf("=== params scope = %p\n", (void*) fun->parameters);
- slang_print_tree(fun->body, 8);
- printf("======================= copied code =========================\n");
- slang_print_tree(inlined, 8);
-#endif
-
- /* do parameter substitution in inlined code: */
- slang_substitute(A, inlined, substCount, substOld, substNew, GL_FALSE);
-
-#if 0
- printf("======================= subst code ==========================\n");
- slang_print_tree(inlined, 8);
- printf("=============================================================\n");
-#endif
-
- /* New prolog statements: (inserted before the inlined code)
- * Copy the 'in' arguments.
- */
- numCopyIn = 0;
- for (i = 0; i < numArgs; i++) {
- if (paramMode[i] == COPY_IN) {
- slang_variable *p = fun->parameters->variables[i];
- /* declare parameter 'p' */
- slang_operation *decl = slang_operation_insert(&inlined->num_children,
- &inlined->children,
- numCopyIn);
-
- decl->type = SLANG_OPER_VARIABLE_DECL;
- assert(decl->locals);
- decl->locals->outer_scope = inlined->locals;
- decl->a_id = p->a_name;
- decl->num_children = 1;
- decl->children = slang_operation_new(1);
-
- /* child[0] is the var's initializer */
- slang_operation_copy(&decl->children[0], args + i);
-
- /* add parameter 'p' to the local variable scope here */
- {
- slang_variable *pCopy = slang_variable_scope_grow(inlined->locals);
- pCopy->type = p->type;
- pCopy->a_name = p->a_name;
- pCopy->array_len = p->array_len;
- }
-
- newScope = inlined->locals;
- numCopyIn++;
- }
- }
-
- /* Now add copies of the function's local vars to the new variable scope */
- for (i = totalArgs; i < fun->parameters->num_variables; i++) {
- slang_variable *p = fun->parameters->variables[i];
- slang_variable *pCopy = slang_variable_scope_grow(inlined->locals);
- pCopy->type = p->type;
- pCopy->a_name = p->a_name;
- pCopy->array_len = p->array_len;
- }
-
-
- /* New epilog statements:
- * 1. Create end of function label to jump to from return statements.
- * 2. Copy the 'out' parameter vars
- */
- {
- slang_operation *lab = slang_operation_insert(&inlined->num_children,
- &inlined->children,
- inlined->num_children);
- lab->type = SLANG_OPER_LABEL;
- lab->label = A->curFuncEndLabel;
- }
-
- for (i = 0; i < totalArgs; i++) {
- if (paramMode[i] == COPY_OUT) {
- const slang_variable *p = fun->parameters->variables[i];
- /* actualCallVar = outParam */
- /*if (i > 0 || !haveRetValue)*/
- slang_operation *ass = slang_operation_insert(&inlined->num_children,
- &inlined->children,
- inlined->num_children);
- ass->type = SLANG_OPER_ASSIGN;
- ass->num_children = 2;
- ass->locals->outer_scope = inlined->locals;
- ass->children = slang_operation_new(2);
- ass->children[0] = args[i]; /*XXX copy */
- ass->children[1].type = SLANG_OPER_IDENTIFIER;
- ass->children[1].a_id = p->a_name;
- ass->children[1].locals->outer_scope = ass->locals;
- }
- }
-
- _slang_free(paramMode);
- _slang_free(substOld);
- _slang_free(substNew);
-
- /* Update scoping to use the new local vars instead of the
- * original function's vars. This is especially important
- * for nested inlining.
- */
- if (newScope)
- slang_replace_scope(inlined, fun->parameters, newScope);
-
-#if 0
- printf("Done Inline call to %s (total vars=%d nparams=%d)\n\n",
- (char *) fun->header.a_name,
- fun->parameters->num_variables, numArgs);
- slang_print_tree(top, 0);
-#endif
-
- /* pop */
- A->CurFunction = prevFunction;
-
- return top;
-}
-
-
-/**
- * Insert declaration for "bool __notRetFlag" in given block operation.
- * This is used when we can't emit "early" return statements in subroutines.
- */
-static void
-declare_return_flag(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_operation *decl;
-
- assert(oper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
- oper->type == SLANG_OPER_SEQUENCE);
-
- decl = slang_operation_insert_child(oper, 1);
-
- slang_generate_declaration(A, oper->locals, decl,
- SLANG_SPEC_BOOL, "__notRetFlag", GL_TRUE);
-
- /*slang_print_tree(oper, 0);*/
-}
-
-
-/**
- * Recursively replace instances of the old node type with the new type.
- */
-static void
-replace_node_type(slang_operation *oper, slang_operation_type oldType,
- slang_operation_type newType)
-{
- GLuint i;
-
- if (oper->type == oldType)
- oper->type = newType;
-
- for (i = 0; i < slang_oper_num_children(oper); i++) {
- replace_node_type(slang_oper_child(oper, i), oldType, newType);
- }
-}
-
-
-
-/**
- * Test if the given function body has an "early return". That is, there's
- * a 'return' statement that's not the very last instruction in the body.
- */
-static GLboolean
-has_early_return(const slang_operation *funcBody)
-{
- GLuint retCount = _slang_count_node_type(funcBody, SLANG_OPER_RETURN);
- if (retCount == 0)
- return GL_FALSE;
- else if (retCount == 1 && _slang_is_tail_return(funcBody))
- return GL_FALSE;
- else
- return GL_TRUE;
-}
-
-
-/**
- * Emit IR code for a function call. This does one of two things:
- * 1. Inline the function's code
- * 2. Create an IR for the function's body and create a real call to it.
- */
-static slang_ir_node *
-_slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun,
- slang_operation *oper, slang_operation *dest)
-{
- slang_ir_node *n;
- slang_operation *instance;
- slang_label *prevFuncEndLabel;
- char name[200];
-
- prevFuncEndLabel = A->curFuncEndLabel;
- _mesa_snprintf(name, sizeof(name), "__endOfFunc_%s_", (char *) fun->header.a_name);
- A->curFuncEndLabel = _slang_label_new(name);
- assert(A->curFuncEndLabel);
-
- /*
- * 'instance' is basically a copy of the function's body with various
- * transformations.
- */
-
- if (slang_is_asm_function(fun) && !dest) {
- /* assemble assembly function - tree style */
- instance = slang_inline_asm_function(A, fun, oper);
- }
- else {
- /* non-assembly function */
- /* We always generate an "inline-able" block of code here.
- * We may either:
- * 1. insert the inline code
- * 2. Generate a call to the "inline" code as a subroutine
- */
- const GLboolean earlyReturn = has_early_return(fun->body);
-
- if (earlyReturn && !A->EmitContReturn) {
- A->UseReturnFlag = GL_TRUE;
- }
-
- instance = slang_inline_function_call(A, fun, oper, dest);
- if (!instance)
- return NULL;
-
- if (earlyReturn) {
- /* The function we're calling has one or more 'return' statements
- * that prevent us from inlining the function's code.
- *
- * In this case, change the function's body type from
- * SLANG_OPER_BLOCK_NEW_SCOPE to SLANG_OPER_NON_INLINED_CALL.
- * During code emit this will result in a true subroutine call.
- *
- * Also, convert SLANG_OPER_RETURN_INLINED nodes to SLANG_OPER_RETURN.
- */
- slang_operation *callOper;
-
- assert(instance->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
- instance->type == SLANG_OPER_SEQUENCE);
-
- if (_slang_function_has_return_value(fun) && !dest) {
- assert(instance->children[0].type == SLANG_OPER_VARIABLE_DECL);
- assert(instance->children[2].type == SLANG_OPER_IDENTIFIER);
- callOper = &instance->children[1];
- }
- else {
- callOper = instance;
- }
-
- if (A->UseReturnFlag) {
- /* Early returns not supported. Create a _returnFlag variable
- * that's set upon 'return' and tested elsewhere to no-op any
- * remaining instructions in the subroutine.
- */
- assert(callOper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
- callOper->type == SLANG_OPER_SEQUENCE);
- declare_return_flag(A, callOper);
- }
- else {
- /* We can emit real 'return' statements. If we generated any
- * 'inline return' statements during function instantiation,
- * change them back to regular 'return' statements.
- */
- replace_node_type(instance, SLANG_OPER_RETURN_INLINED,
- SLANG_OPER_RETURN);
- }
-
- callOper->type = SLANG_OPER_NON_INLINED_CALL;
- callOper->fun = fun;
- callOper->label = _slang_label_new_unique((char*) fun->header.a_name);
- }
- else {
- /* If there are any 'return' statements remaining, they're at the
- * very end of the function and can effectively become no-ops.
- */
- replace_node_type(instance, SLANG_OPER_RETURN_INLINED,
- SLANG_OPER_VOID);
- }
- }
-
- if (!instance)
- return NULL;
-
- /* Replace the function call with the instance block (or new CALL stmt) */
- slang_operation_destruct(oper);
- *oper = *instance;
- _slang_free(instance);
-
-#if 0
- assert(instance->locals);
- printf("*** Inlined code for call to %s:\n", (char*) fun->header.a_name);
- slang_print_tree(oper, 10);
- printf("\n");
-#endif
-
- n = _slang_gen_operation(A, oper);
-
- /*_slang_label_delete(A->curFuncEndLabel);*/
- A->curFuncEndLabel = prevFuncEndLabel;
-
- if (A->pragmas->Debug) {
- char s[1000];
- _mesa_snprintf(s, sizeof(s), "Call/inline %s()", (char *) fun->header.a_name);
- n->Comment = _slang_strdup(s);
- }
-
- A->UseReturnFlag = GL_FALSE;
-
- return n;
-}
-
-
-static slang_asm_info *
-slang_find_asm_info(const char *name)
-{
- GLuint i;
- for (i = 0; AsmInfo[i].Name; i++) {
- if (strcmp(AsmInfo[i].Name, name) == 0) {
- return AsmInfo + i;
- }
- }
- return NULL;
-}
-
-
-/**
- * Some write-masked assignments are simple, but others are hard.
- * Simple example:
- * vec3 v;
- * v.xy = vec2(a, b);
- * Hard example:
- * vec3 v;
- * v.zy = vec2(a, b);
- * this gets transformed/swizzled into:
- * v.zy = vec2(a, b).*yx* (* = don't care)
- * This function helps to determine simple vs. non-simple.
- */
-static GLboolean
-_slang_simple_writemask(GLuint writemask, GLuint swizzle)
-{
- switch (writemask) {
- case WRITEMASK_X:
- return GET_SWZ(swizzle, 0) == SWIZZLE_X;
- case WRITEMASK_Y:
- return GET_SWZ(swizzle, 1) == SWIZZLE_Y;
- case WRITEMASK_Z:
- return GET_SWZ(swizzle, 2) == SWIZZLE_Z;
- case WRITEMASK_W:
- return GET_SWZ(swizzle, 3) == SWIZZLE_W;
- case WRITEMASK_XY:
- return (GET_SWZ(swizzle, 0) == SWIZZLE_X)
- && (GET_SWZ(swizzle, 1) == SWIZZLE_Y);
- case WRITEMASK_XYZ:
- return (GET_SWZ(swizzle, 0) == SWIZZLE_X)
- && (GET_SWZ(swizzle, 1) == SWIZZLE_Y)
- && (GET_SWZ(swizzle, 2) == SWIZZLE_Z);
- case WRITEMASK_XYZW:
- return swizzle == SWIZZLE_NOOP;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Convert the given swizzle into a writemask. In some cases this
- * is trivial, in other cases, we'll need to also swizzle the right
- * hand side to put components in the right places.
- * See comment above for more info.
- * XXX this function could be simplified and should probably be renamed.
- * \param swizzle the incoming swizzle
- * \param writemaskOut returns the writemask
- * \param swizzleOut swizzle to apply to the right-hand-side
- * \return GL_FALSE for simple writemasks, GL_TRUE for non-simple
- */
-static GLboolean
-swizzle_to_writemask(slang_assemble_ctx *A, GLuint swizzle,
- GLuint *writemaskOut, GLuint *swizzleOut)
-{
- GLuint mask = 0x0, newSwizzle[4];
- GLint i, size;
-
- /* make new dst writemask, compute size */
- for (i = 0; i < 4; i++) {
- const GLuint swz = GET_SWZ(swizzle, i);
- if (swz == SWIZZLE_NIL) {
- /* end */
- break;
- }
- assert(swz <= 3);
-
- if (swizzle != SWIZZLE_XXXX &&
- swizzle != SWIZZLE_YYYY &&
- swizzle != SWIZZLE_ZZZZ &&
- swizzle != SWIZZLE_WWWW &&
- (mask & (1 << swz))) {
- /* a channel can't be specified twice (ex: ".xyyz") */
- slang_info_log_error(A->log, "Invalid writemask '%s'",
- _mesa_swizzle_string(swizzle, 0, 0));
- return GL_FALSE;
- }
-
- mask |= (1 << swz);
- }
- assert(mask <= 0xf);
- size = i; /* number of components in mask/swizzle */
-
- *writemaskOut = mask;
-
- /* make new src swizzle, by inversion */
- for (i = 0; i < 4; i++) {
- newSwizzle[i] = i; /*identity*/
- }
- for (i = 0; i < size; i++) {
- const GLuint swz = GET_SWZ(swizzle, i);
- newSwizzle[swz] = i;
- }
- *swizzleOut = MAKE_SWIZZLE4(newSwizzle[0],
- newSwizzle[1],
- newSwizzle[2],
- newSwizzle[3]);
-
- if (_slang_simple_writemask(mask, *swizzleOut)) {
- if (size >= 1)
- assert(GET_SWZ(*swizzleOut, 0) == SWIZZLE_X);
- if (size >= 2)
- assert(GET_SWZ(*swizzleOut, 1) == SWIZZLE_Y);
- if (size >= 3)
- assert(GET_SWZ(*swizzleOut, 2) == SWIZZLE_Z);
- if (size >= 4)
- assert(GET_SWZ(*swizzleOut, 3) == SWIZZLE_W);
- return GL_TRUE;
- }
- else
- return GL_FALSE;
-}
-
-
-#if 0 /* not used, but don't remove just yet */
-/**
- * Recursively traverse 'oper' to produce a swizzle mask in the event
- * of any vector subscripts and swizzle suffixes.
- * Ex: for "vec4 v", "v[2].x" resolves to v.z
- */
-static GLuint
-resolve_swizzle(const slang_operation *oper)
-{
- if (oper->type == SLANG_OPER_FIELD) {
- /* writemask from .xyzw suffix */
- slang_swizzle swz;
- if (_slang_is_swizzle((char*) oper->a_id, 4, &swz)) {
- GLuint swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
- swz.swizzle[1],
- swz.swizzle[2],
- swz.swizzle[3]);
- GLuint child_swizzle = resolve_swizzle(&oper->children[0]);
- GLuint s = _slang_swizzle_swizzle(child_swizzle, swizzle);
- return s;
- }
- else
- return SWIZZLE_XYZW;
- }
- else if (oper->type == SLANG_OPER_SUBSCRIPT &&
- oper->children[1].type == SLANG_OPER_LITERAL_INT) {
- /* writemask from [index] */
- GLuint child_swizzle = resolve_swizzle(&oper->children[0]);
- GLuint i = (GLuint) oper->children[1].literal[0];
- GLuint swizzle;
- GLuint s;
- switch (i) {
- case 0:
- swizzle = SWIZZLE_XXXX;
- break;
- case 1:
- swizzle = SWIZZLE_YYYY;
- break;
- case 2:
- swizzle = SWIZZLE_ZZZZ;
- break;
- case 3:
- swizzle = SWIZZLE_WWWW;
- break;
- default:
- swizzle = SWIZZLE_XYZW;
- }
- s = _slang_swizzle_swizzle(child_swizzle, swizzle);
- return s;
- }
- else {
- return SWIZZLE_XYZW;
- }
-}
-#endif
-
-
-#if 0
-/**
- * Recursively descend through swizzle nodes to find the node's storage info.
- */
-static slang_ir_storage *
-get_store(const slang_ir_node *n)
-{
- if (n->Opcode == IR_SWIZZLE) {
- return get_store(n->Children[0]);
- }
- return n->Store;
-}
-#endif
-
-
-/**
- * Generate IR tree for an asm instruction/operation such as:
- * __asm vec4_dot __retVal.x, v1, v2;
- */
-static slang_ir_node *
-_slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper,
- slang_operation *dest)
-{
- const slang_asm_info *info;
- slang_ir_node *kids[3], *n;
- GLuint j, firstOperand;
-
- assert(oper->type == SLANG_OPER_ASM);
-
- info = slang_find_asm_info((char *) oper->a_id);
- if (!info) {
- _mesa_problem(NULL, "undefined __asm function %s\n",
- (char *) oper->a_id);
- assert(info);
- return NULL;
- }
- assert(info->NumParams <= 3);
-
- if (info->NumParams == oper->num_children) {
- /* Storage for result is not specified.
- * Children[0], [1], [2] are the operands.
- */
- firstOperand = 0;
- }
- else {
- /* Storage for result (child[0]) is specified.
- * Children[1], [2], [3] are the operands.
- */
- firstOperand = 1;
- }
-
- /* assemble child(ren) */
- kids[0] = kids[1] = kids[2] = NULL;
- for (j = 0; j < info->NumParams; j++) {
- kids[j] = _slang_gen_operation(A, &oper->children[firstOperand + j]);
- if (!kids[j])
- return NULL;
- }
-
- n = new_node3(info->Opcode, kids[0], kids[1], kids[2]);
-
- if (firstOperand) {
- /* Setup n->Store to be a particular location. Otherwise, storage
- * for the result (a temporary) will be allocated later.
- */
- slang_operation *dest_oper;
- slang_ir_node *n0;
-
- dest_oper = &oper->children[0];
-
- n0 = _slang_gen_operation(A, dest_oper);
- if (!n0)
- return NULL;
-
- assert(!n->Store);
- n->Store = n0->Store;
-
- assert(n->Store->File != PROGRAM_UNDEFINED || n->Store->Parent);
-
- _slang_free(n0);
- }
-
- return n;
-}
-
-
-#if 0
-static void
-print_funcs(struct slang_function_scope_ *scope, const char *name)
-{
- GLuint i;
- for (i = 0; i < scope->num_functions; i++) {
- slang_function *f = &scope->functions[i];
- if (!name || strcmp(name, (char*) f->header.a_name) == 0)
- printf(" %s (%d args)\n", name, f->param_count);
-
- }
- if (scope->outer_scope)
- print_funcs(scope->outer_scope, name);
-}
-#endif
-
-
-/**
- * Find a function of the given name, taking 'numArgs' arguments.
- * This is the function we'll try to call when there is no exact match
- * between function parameters and call arguments.
- *
- * XXX we should really create a list of candidate functions and try
- * all of them...
- */
-static slang_function *
-_slang_find_function_by_argc(slang_function_scope *scope,
- const char *name, int numArgs)
-{
- while (scope) {
- GLuint i;
- for (i = 0; i < scope->num_functions; i++) {
- slang_function *f = &scope->functions[i];
- if (strcmp(name, (char*) f->header.a_name) == 0) {
- int haveRetValue = _slang_function_has_return_value(f);
- if (numArgs == f->param_count - haveRetValue)
- return f;
- }
- }
- scope = scope->outer_scope;
- }
-
- return NULL;
-}
-
-
-static slang_function *
-_slang_find_function_by_max_argc(slang_function_scope *scope,
- const char *name)
-{
- slang_function *maxFunc = NULL;
- GLuint maxArgs = 0;
-
- while (scope) {
- GLuint i;
- for (i = 0; i < scope->num_functions; i++) {
- slang_function *f = &scope->functions[i];
- if (strcmp(name, (char*) f->header.a_name) == 0) {
- if (f->param_count > maxArgs) {
- maxArgs = f->param_count;
- maxFunc = f;
- }
- }
- }
- scope = scope->outer_scope;
- }
-
- return maxFunc;
-}
-
-
-/**
- * Generate a new slang_function which is a constructor for a user-defined
- * struct type.
- */
-static slang_function *
-_slang_make_struct_constructor(slang_assemble_ctx *A, slang_struct *str)
-{
- const GLint numFields = str->fields->num_variables;
- slang_function *fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR);
-
- /* function header (name, return type) */
- fun->header.a_name = str->a_name;
- fun->header.type.qualifier = SLANG_QUAL_NONE;
- fun->header.type.specifier.type = SLANG_SPEC_STRUCT;
- fun->header.type.specifier._struct = str;
-
- /* function parameters (= struct's fields) */
- {
- GLint i;
- for (i = 0; i < numFields; i++) {
- /*
- printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name);
- */
- slang_variable *p = slang_variable_scope_grow(fun->parameters);
- *p = *str->fields->variables[i]; /* copy the variable and type */
- p->type.qualifier = SLANG_QUAL_CONST;
- }
- fun->param_count = fun->parameters->num_variables;
- }
-
- /* Add __retVal to params */
- {
- slang_variable *p = slang_variable_scope_grow(fun->parameters);
- slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
- assert(a_retVal);
- p->a_name = a_retVal;
- p->type = fun->header.type;
- p->type.qualifier = SLANG_QUAL_OUT;
- fun->param_count++;
- }
-
- /* function body is:
- * block:
- * declare T;
- * T.f1 = p1;
- * T.f2 = p2;
- * ...
- * T.fn = pn;
- * return T;
- */
- {
- slang_variable_scope *scope;
- slang_variable *var;
- GLint i;
-
- fun->body = slang_operation_new(1);
- fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE;
- fun->body->num_children = numFields + 2;
- fun->body->children = slang_operation_new(numFields + 2);
-
- scope = fun->body->locals;
- scope->outer_scope = fun->parameters;
-
- /* create local var 't' */
- var = slang_variable_scope_grow(scope);
- var->a_name = slang_atom_pool_atom(A->atoms, "t");
- var->type = fun->header.type;
-
- /* declare t */
- {
- slang_operation *decl;
-
- decl = &fun->body->children[0];
- decl->type = SLANG_OPER_VARIABLE_DECL;
- decl->locals = _slang_variable_scope_new(scope);
- decl->a_id = var->a_name;
- }
-
- /* assign params to fields of t */
- for (i = 0; i < numFields; i++) {
- slang_operation *assign = &fun->body->children[1 + i];
-
- assign->type = SLANG_OPER_ASSIGN;
- assign->locals = _slang_variable_scope_new(scope);
- assign->num_children = 2;
- assign->children = slang_operation_new(2);
-
- {
- slang_operation *lhs = &assign->children[0];
-
- lhs->type = SLANG_OPER_FIELD;
- lhs->locals = _slang_variable_scope_new(scope);
- lhs->num_children = 1;
- lhs->children = slang_operation_new(1);
- lhs->a_id = str->fields->variables[i]->a_name;
-
- lhs->children[0].type = SLANG_OPER_IDENTIFIER;
- lhs->children[0].a_id = var->a_name;
- lhs->children[0].locals = _slang_variable_scope_new(scope);
-
-#if 0
- lhs->children[1].num_children = 1;
- lhs->children[1].children = slang_operation_new(1);
- lhs->children[1].children[0].type = SLANG_OPER_IDENTIFIER;
- lhs->children[1].children[0].a_id = str->fields->variables[i]->a_name;
- lhs->children[1].children->locals = _slang_variable_scope_new(scope);
-#endif
- }
-
- {
- slang_operation *rhs = &assign->children[1];
-
- rhs->type = SLANG_OPER_IDENTIFIER;
- rhs->locals = _slang_variable_scope_new(scope);
- rhs->a_id = str->fields->variables[i]->a_name;
- }
- }
-
- /* return t; */
- {
- slang_operation *ret = &fun->body->children[numFields + 1];
-
- ret->type = SLANG_OPER_RETURN;
- ret->locals = _slang_variable_scope_new(scope);
- ret->num_children = 1;
- ret->children = slang_operation_new(1);
- ret->children[0].type = SLANG_OPER_IDENTIFIER;
- ret->children[0].a_id = var->a_name;
- ret->children[0].locals = _slang_variable_scope_new(scope);
- }
- }
- /*
- slang_print_function(fun, 1);
- */
- return fun;
-}
-
-
-/**
- * Find/create a function (constructor) for the given structure name.
- */
-static slang_function *
-_slang_locate_struct_constructor(slang_assemble_ctx *A, const char *name)
-{
- unsigned int i;
- for (i = 0; i < A->space.structs->num_structs; i++) {
- slang_struct *str = &A->space.structs->structs[i];
- if (strcmp(name, (const char *) str->a_name) == 0) {
- /* found a structure type that matches the function name */
- if (!str->constructor) {
- /* create the constructor function now */
- str->constructor = _slang_make_struct_constructor(A, str);
- }
- return str->constructor;
- }
- }
- return NULL;
-}
-
-
-/**
- * Generate a new slang_function to satisfy a call to an array constructor.
- * Ex: float[3](1., 2., 3.)
- */
-static slang_function *
-_slang_make_array_constructor(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_type_specifier_type baseType;
- slang_function *fun;
- int num_elements;
-
- fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR);
- if (!fun)
- return NULL;
-
- baseType = slang_type_specifier_type_from_string((char *) oper->a_id);
-
- num_elements = oper->num_children;
-
- /* function header, return type */
- {
- fun->header.a_name = oper->a_id;
- fun->header.type.qualifier = SLANG_QUAL_NONE;
- fun->header.type.specifier.type = SLANG_SPEC_ARRAY;
- fun->header.type.specifier._array =
- slang_type_specifier_new(baseType, NULL, NULL);
- fun->header.type.array_len = num_elements;
- }
-
- /* function parameters (= number of elements) */
- {
- GLint i;
- for (i = 0; i < num_elements; i++) {
- /*
- printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name);
- */
- slang_variable *p = slang_variable_scope_grow(fun->parameters);
- char name[10];
- _mesa_snprintf(name, sizeof(name), "p%d", i);
- p->a_name = slang_atom_pool_atom(A->atoms, name);
- p->type.qualifier = SLANG_QUAL_CONST;
- p->type.specifier.type = baseType;
- }
- fun->param_count = fun->parameters->num_variables;
- }
-
- /* Add __retVal to params */
- {
- slang_variable *p = slang_variable_scope_grow(fun->parameters);
- slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
- assert(a_retVal);
- p->a_name = a_retVal;
- p->type = fun->header.type;
- p->type.qualifier = SLANG_QUAL_OUT;
- p->type.specifier.type = baseType;
- fun->param_count++;
- }
-
- /* function body is:
- * block:
- * declare T;
- * T[0] = p0;
- * T[1] = p1;
- * ...
- * T[n] = pn;
- * return T;
- */
- {
- slang_variable_scope *scope;
- slang_variable *var;
- GLint i;
-
- fun->body = slang_operation_new(1);
- fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE;
- fun->body->num_children = num_elements + 2;
- fun->body->children = slang_operation_new(num_elements + 2);
-
- scope = fun->body->locals;
- scope->outer_scope = fun->parameters;
-
- /* create local var 't' */
- var = slang_variable_scope_grow(scope);
- var->a_name = slang_atom_pool_atom(A->atoms, "ttt");
- var->type = fun->header.type;/*XXX copy*/
-
- /* declare t */
- {
- slang_operation *decl;
-
- decl = &fun->body->children[0];
- decl->type = SLANG_OPER_VARIABLE_DECL;
- decl->locals = _slang_variable_scope_new(scope);
- decl->a_id = var->a_name;
- }
-
- /* assign params to elements of t */
- for (i = 0; i < num_elements; i++) {
- slang_operation *assign = &fun->body->children[1 + i];
-
- assign->type = SLANG_OPER_ASSIGN;
- assign->locals = _slang_variable_scope_new(scope);
- assign->num_children = 2;
- assign->children = slang_operation_new(2);
-
- {
- slang_operation *lhs = &assign->children[0];
-
- lhs->type = SLANG_OPER_SUBSCRIPT;
- lhs->locals = _slang_variable_scope_new(scope);
- lhs->num_children = 2;
- lhs->children = slang_operation_new(2);
-
- lhs->children[0].type = SLANG_OPER_IDENTIFIER;
- lhs->children[0].a_id = var->a_name;
- lhs->children[0].locals = _slang_variable_scope_new(scope);
-
- lhs->children[1].type = SLANG_OPER_LITERAL_INT;
- lhs->children[1].literal[0] = (GLfloat) i;
- }
-
- {
- slang_operation *rhs = &assign->children[1];
-
- rhs->type = SLANG_OPER_IDENTIFIER;
- rhs->locals = _slang_variable_scope_new(scope);
- rhs->a_id = fun->parameters->variables[i]->a_name;
- }
- }
-
- /* return t; */
- {
- slang_operation *ret = &fun->body->children[num_elements + 1];
-
- ret->type = SLANG_OPER_RETURN;
- ret->locals = _slang_variable_scope_new(scope);
- ret->num_children = 1;
- ret->children = slang_operation_new(1);
- ret->children[0].type = SLANG_OPER_IDENTIFIER;
- ret->children[0].a_id = var->a_name;
- ret->children[0].locals = _slang_variable_scope_new(scope);
- }
- }
-
- /*
- slang_print_function(fun, 1);
- */
-
- return fun;
-}
-
-
-static GLboolean
-_slang_is_vec_mat_type(const char *name)
-{
- static const char *vecmat_types[] = {
- "float", "int", "bool",
- "vec2", "vec3", "vec4",
- "ivec2", "ivec3", "ivec4",
- "bvec2", "bvec3", "bvec4",
- "mat2", "mat3", "mat4",
- "mat2x3", "mat2x4", "mat3x2", "mat3x4", "mat4x2", "mat4x3",
- NULL
- };
- int i;
- for (i = 0; vecmat_types[i]; i++)
- if (strcmp(name, vecmat_types[i]) == 0)
- return GL_TRUE;
- return GL_FALSE;
-}
-
-
-/**
- * Assemble a function call, given a particular function name.
- * \param name the function's name (operators like '*' are possible).
- */
-static slang_ir_node *
-_slang_gen_function_call_name(slang_assemble_ctx *A, const char *name,
- slang_operation *oper, slang_operation *dest)
-{
- slang_operation *params = oper->children;
- const GLuint param_count = oper->num_children;
- slang_atom atom;
- slang_function *fun;
- slang_ir_node *n;
-
- atom = slang_atom_pool_atom(A->atoms, name);
- if (atom == SLANG_ATOM_NULL)
- return NULL;
-
- if (oper->array_constructor) {
- /* this needs special handling */
- fun = _slang_make_array_constructor(A, oper);
- }
- else {
- /* Try to find function by name and exact argument type matching */
- GLboolean error = GL_FALSE;
- fun = _slang_function_locate(A->space.funcs, atom, params, param_count,
- &A->space, A->atoms, A->log, &error);
- if (error) {
- slang_info_log_error(A->log,
- "Function '%s' not found (check argument types)",
- name);
- return NULL;
- }
- }
-
- if (!fun) {
- /* Next, try locating a constructor function for a user-defined type */
- fun = _slang_locate_struct_constructor(A, name);
- }
-
- /*
- * At this point, some heuristics are used to try to find a function
- * that matches the calling signature by means of casting or "unrolling"
- * of constructors.
- */
-
- if (!fun && _slang_is_vec_mat_type(name)) {
- /* Next, if this call looks like a vec() or mat() constructor call,
- * try "unwinding" the args to satisfy a constructor.
- */
- fun = _slang_find_function_by_max_argc(A->space.funcs, name);
- if (fun) {
- if (!_slang_adapt_call(oper, fun, &A->space, A->atoms, A->log)) {
- slang_info_log_error(A->log,
- "Function '%s' not found (check argument types)",
- name);
- return NULL;
- }
- }
- }
-
- if (!fun && _slang_is_vec_mat_type(name)) {
- /* Next, try casting args to the types of the formal parameters */
- int numArgs = oper->num_children;
- fun = _slang_find_function_by_argc(A->space.funcs, name, numArgs);
- if (!fun || !_slang_cast_func_params(oper, fun, &A->space, A->atoms, A->log)) {
- slang_info_log_error(A->log,
- "Function '%s' not found (check argument types)",
- name);
- return NULL;
- }
- assert(fun);
- }
-
- if (!fun) {
- slang_info_log_error(A->log,
- "Function '%s' not found (check argument types)",
- name);
- return NULL;
- }
-
- if (!fun->body) {
- /* The function body may be in another compilation unit.
- * We'll try concatenating the shaders and recompile at link time.
- */
- A->UnresolvedRefs = GL_TRUE;
- return new_node1(IR_NOP, NULL);
- }
-
- /* type checking to be sure function's return type matches 'dest' type */
- if (dest) {
- slang_typeinfo t0;
-
- slang_typeinfo_construct(&t0);
- typeof_operation(A, dest, &t0);
-
- if (!slang_type_specifier_equal(&t0.spec, &fun->header.type.specifier)) {
- slang_info_log_error(A->log,
- "Incompatible type returned by call to '%s'",
- name);
- return NULL;
- }
- }
-
- n = _slang_gen_function_call(A, fun, oper, dest);
-
- if (n && !n->Store && !dest
- && fun->header.type.specifier.type != SLANG_SPEC_VOID) {
- /* setup n->Store for the result of the function call */
- GLint size = _slang_sizeof_type_specifier(&fun->header.type.specifier);
- n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size);
- /*printf("Alloc storage for function result, size %d \n", size);*/
- }
-
- if (oper->array_constructor) {
- /* free the temporary array constructor function now */
- slang_function_destruct(fun);
- }
-
- return n;
-}
-
-
-static slang_ir_node *
-_slang_gen_method_call(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_atom *a_length = slang_atom_pool_atom(A->atoms, "length");
- slang_ir_node *n;
- slang_variable *var;
-
- /* NOTE: In GLSL 1.20, there's only one kind of method
- * call: array.length(). Anything else is an error.
- */
- if (oper->a_id != a_length) {
- slang_info_log_error(A->log,
- "Undefined method call '%s'", (char *) oper->a_id);
- return NULL;
- }
-
- /* length() takes no arguments */
- if (oper->num_children > 0) {
- slang_info_log_error(A->log, "Invalid arguments to length() method");
- return NULL;
- }
-
- /* lookup the object/variable */
- var = _slang_variable_locate(oper->locals, oper->a_obj, GL_TRUE);
- if (!var || var->type.specifier.type != SLANG_SPEC_ARRAY) {
- slang_info_log_error(A->log,
- "Undefined object '%s'", (char *) oper->a_obj);
- return NULL;
- }
-
- /* Create a float/literal IR node encoding the array length */
- n = new_node0(IR_FLOAT);
- if (n) {
- n->Value[0] = (float) _slang_array_length(var);
- n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, 1);
- }
- return n;
-}
-
-
-static GLboolean
-_slang_is_constant_cond(const slang_operation *oper, GLboolean *value)
-{
- if (oper->type == SLANG_OPER_LITERAL_FLOAT ||
- oper->type == SLANG_OPER_LITERAL_INT ||
- oper->type == SLANG_OPER_LITERAL_BOOL) {
- if (oper->literal[0])
- *value = GL_TRUE;
- else
- *value = GL_FALSE;
- return GL_TRUE;
- }
- else if (oper->type == SLANG_OPER_EXPRESSION &&
- oper->num_children == 1) {
- return _slang_is_constant_cond(&oper->children[0], value);
- }
- return GL_FALSE;
-}
-
-
-/**
- * Test if an operation is a scalar or boolean.
- */
-static GLboolean
-_slang_is_scalar_or_boolean(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_typeinfo type;
- GLint size;
-
- slang_typeinfo_construct(&type);
- typeof_operation(A, oper, &type);
- size = _slang_sizeof_type_specifier(&type.spec);
- slang_typeinfo_destruct(&type);
- return size == 1;
-}
-
-
-/**
- * Test if an operation is boolean.
- */
-static GLboolean
-_slang_is_boolean(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_typeinfo type;
- GLboolean isBool;
-
- slang_typeinfo_construct(&type);
- typeof_operation(A, oper, &type);
- isBool = (type.spec.type == SLANG_SPEC_BOOL);
- slang_typeinfo_destruct(&type);
- return isBool;
-}
-
-
-/**
- * Check if a loop contains a 'continue' statement.
- * Stop looking if we find a nested loop.
- */
-static GLboolean
-_slang_loop_contains_continue(const slang_operation *oper)
-{
- switch (oper->type) {
- case SLANG_OPER_CONTINUE:
- return GL_TRUE;
- case SLANG_OPER_FOR:
- case SLANG_OPER_DO:
- case SLANG_OPER_WHILE:
- /* stop upon finding a nested loop */
- return GL_FALSE;
- default:
- /* recurse */
- {
- GLuint i;
- for (i = 0; i < oper->num_children; i++) {
- const slang_operation *child = slang_oper_child_const(oper, i);
- if (_slang_loop_contains_continue(child))
- return GL_TRUE;
- }
- }
- return GL_FALSE;
- }
-}
-
-
-/**
- * Check if a loop contains a 'continue' or 'break' statement.
- * Stop looking if we find a nested loop.
- */
-static GLboolean
-_slang_loop_contains_continue_or_break(const slang_operation *oper)
-{
- switch (oper->type) {
- case SLANG_OPER_CONTINUE:
- case SLANG_OPER_BREAK:
- return GL_TRUE;
- case SLANG_OPER_FOR:
- case SLANG_OPER_DO:
- case SLANG_OPER_WHILE:
- /* stop upon finding a nested loop */
- return GL_FALSE;
- default:
- /* recurse */
- {
- GLuint i;
- for (i = 0; i < oper->num_children; i++) {
- const slang_operation *child = slang_oper_child_const(oper, i);
- if (_slang_loop_contains_continue_or_break(child))
- return GL_TRUE;
- }
- }
- return GL_FALSE;
- }
-}
-
-
-/**
- * Replace 'break' and 'continue' statements inside a do and while loops.
- * This is a recursive helper function used by
- * _slang_gen_do/while_without_continue().
- */
-static void
-replace_break_and_cont(slang_assemble_ctx *A, slang_operation *oper)
-{
- switch (oper->type) {
- case SLANG_OPER_BREAK:
- /* replace 'break' with "_notBreakFlag = false; break" */
- {
- slang_operation *block = oper;
- block->type = SLANG_OPER_BLOCK_NEW_SCOPE;
- slang_operation_add_children(block, 2);
- {
- slang_operation *assign = slang_oper_child(block, 0);
- assign->type = SLANG_OPER_ASSIGN;
- slang_operation_add_children(assign, 2);
- {
- slang_operation *lhs = slang_oper_child(assign, 0);
- slang_operation_identifier(lhs, A, "_notBreakFlag");
- }
- {
- slang_operation *rhs = slang_oper_child(assign, 1);
- slang_operation_literal_bool(rhs, GL_FALSE);
- }
- }
- {
- slang_operation *brk = slang_oper_child(block, 1);
- brk->type = SLANG_OPER_BREAK;
- assert(!brk->children);
- }
- }
- break;
- case SLANG_OPER_CONTINUE:
- /* convert continue into a break */
- oper->type = SLANG_OPER_BREAK;
- break;
- case SLANG_OPER_FOR:
- case SLANG_OPER_DO:
- case SLANG_OPER_WHILE:
- /* stop upon finding a nested loop */
- break;
- default:
- /* recurse */
- {
- GLuint i;
- for (i = 0; i < oper->num_children; i++) {
- replace_break_and_cont(A, slang_oper_child(oper, i));
- }
- }
- }
-}
-
-
-/**
- * Transform a while-loop so that continue statements are converted to breaks.
- * Then do normal IR code generation.
- *
- * Before:
- *
- * while (LOOPCOND) {
- * A;
- * if (IFCOND)
- * continue;
- * B;
- * break;
- * C;
- * }
- *
- * After:
- *
- * {
- * bool _notBreakFlag = 1;
- * while (_notBreakFlag && LOOPCOND) {
- * do {
- * A;
- * if (IFCOND) {
- * break; // was continue
- * }
- * B;
- * _notBreakFlag = 0; // was
- * break; // break
- * C;
- * } while (0)
- * }
- * }
- */
-static slang_ir_node *
-_slang_gen_while_without_continue(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_operation *top;
- slang_operation *innerBody;
-
- assert(oper->type == SLANG_OPER_WHILE);
-
- top = slang_operation_new(1);
- top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
- top->locals->outer_scope = oper->locals->outer_scope;
- slang_operation_add_children(top, 2);
-
- /* declare: bool _notBreakFlag = true */
- {
- slang_operation *condDecl = slang_oper_child(top, 0);
- slang_generate_declaration(A, top->locals, condDecl,
- SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE);
- }
-
- /* build outer while-loop: while (_notBreakFlag && LOOPCOND) { ... } */
- {
- slang_operation *outerWhile = slang_oper_child(top, 1);
- outerWhile->type = SLANG_OPER_WHILE;
- slang_operation_add_children(outerWhile, 2);
-
- /* _notBreakFlag && LOOPCOND */
- {
- slang_operation *cond = slang_oper_child(outerWhile, 0);
- cond->type = SLANG_OPER_LOGICALAND;
- slang_operation_add_children(cond, 2);
- {
- slang_operation *notBreak = slang_oper_child(cond, 0);
- slang_operation_identifier(notBreak, A, "_notBreakFlag");
- }
- {
- slang_operation *origCond = slang_oper_child(cond, 1);
- slang_operation_copy(origCond, slang_oper_child(oper, 0));
- }
- }
-
- /* inner loop */
- {
- slang_operation *innerDo = slang_oper_child(outerWhile, 1);
- innerDo->type = SLANG_OPER_DO;
- slang_operation_add_children(innerDo, 2);
-
- /* copy original do-loop body into inner do-loop's body */
- innerBody = slang_oper_child(innerDo, 0);
- slang_operation_copy(innerBody, slang_oper_child(oper, 1));
- innerBody->locals->outer_scope = innerDo->locals;
-
- /* inner do-loop's condition is constant/false */
- {
- slang_operation *constFalse = slang_oper_child(innerDo, 1);
- slang_operation_literal_bool(constFalse, GL_FALSE);
- }
- }
- }
-
- /* Finally, in innerBody,
- * replace "break" with "_notBreakFlag = 0; break"
- * replace "continue" with "break"
- */
- replace_break_and_cont(A, innerBody);
-
- /*slang_print_tree(top, 0);*/
-
- return _slang_gen_operation(A, top);
-
- return NULL;
-}
-
-
-/**
- * Generate loop code using high-level IR_LOOP instruction
- */
-static slang_ir_node *
-_slang_gen_while(slang_assemble_ctx * A, slang_operation *oper)
-{
- /*
- * LOOP:
- * BREAK if !expr (child[0])
- * body code (child[1])
- */
- slang_ir_node *loop, *breakIf, *body;
- GLboolean isConst, constTrue = GL_FALSE;
-
- if (!A->EmitContReturn) {
- /* We don't want to emit CONT instructions. If this while-loop has
- * a continue, translate it away.
- */
- if (_slang_loop_contains_continue(slang_oper_child(oper, 1))) {
- return _slang_gen_while_without_continue(A, oper);
- }
- }
-
- /* type-check expression */
- if (!_slang_is_boolean(A, &oper->children[0])) {
- slang_info_log_error(A->log, "scalar/boolean expression expected for 'while'");
- return NULL;
- }
-
- /* Check if loop condition is a constant */
- isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);
-
- if (isConst && !constTrue) {
- /* loop is never executed! */
- return new_node0(IR_NOP);
- }
-
- /* Begin new loop */
- loop = new_loop(NULL);
-
- /* save loop state */
- push_loop(A, oper, loop);
-
- if (isConst && constTrue) {
- /* while(nonzero constant), no conditional break */
- breakIf = NULL;
- }
- else {
- slang_ir_node *cond
- = new_cond(new_not(_slang_gen_operation(A, &oper->children[0])));
- breakIf = new_break_if_true(A, cond);
- }
- body = _slang_gen_operation(A, &oper->children[1]);
- loop->Children[0] = new_seq(breakIf, body);
-
- /* Do infinite loop detection */
- /* loop->List is head of linked list of break/continue nodes */
- if (!loop->List && isConst && constTrue) {
- /* infinite loop detected */
- pop_loop(A);
- slang_info_log_error(A->log, "Infinite loop detected!");
- return NULL;
- }
-
- /* restore loop state */
- pop_loop(A);
-
- return loop;
-}
-
-
-/**
- * Transform a do-while-loop so that continue statements are converted to breaks.
- * Then do normal IR code generation.
- *
- * Before:
- *
- * do {
- * A;
- * if (IFCOND)
- * continue;
- * B;
- * break;
- * C;
- * } while (LOOPCOND);
- *
- * After:
- *
- * {
- * bool _notBreakFlag = 1;
- * do {
- * do {
- * A;
- * if (IFCOND) {
- * break; // was continue
- * }
- * B;
- * _notBreakFlag = 0; // was
- * break; // break
- * C;
- * } while (0)
- * } while (_notBreakFlag && LOOPCOND);
- * }
- */
-static slang_ir_node *
-_slang_gen_do_without_continue(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_operation *top;
- slang_operation *innerBody;
-
- assert(oper->type == SLANG_OPER_DO);
-
- top = slang_operation_new(1);
- top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
- top->locals->outer_scope = oper->locals->outer_scope;
- slang_operation_add_children(top, 2);
-
- /* declare: bool _notBreakFlag = true */
- {
- slang_operation *condDecl = slang_oper_child(top, 0);
- slang_generate_declaration(A, top->locals, condDecl,
- SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE);
- }
-
- /* build outer do-loop: do { ... } while (_notBreakFlag && LOOPCOND) */
- {
- slang_operation *outerDo = slang_oper_child(top, 1);
- outerDo->type = SLANG_OPER_DO;
- slang_operation_add_children(outerDo, 2);
-
- /* inner do-loop */
- {
- slang_operation *innerDo = slang_oper_child(outerDo, 0);
- innerDo->type = SLANG_OPER_DO;
- slang_operation_add_children(innerDo, 2);
-
- /* copy original do-loop body into inner do-loop's body */
- innerBody = slang_oper_child(innerDo, 0);
- slang_operation_copy(innerBody, slang_oper_child(oper, 0));
- innerBody->locals->outer_scope = innerDo->locals;
-
- /* inner do-loop's condition is constant/false */
- {
- slang_operation *constFalse = slang_oper_child(innerDo, 1);
- slang_operation_literal_bool(constFalse, GL_FALSE);
- }
- }
-
- /* _notBreakFlag && LOOPCOND */
- {
- slang_operation *cond = slang_oper_child(outerDo, 1);
- cond->type = SLANG_OPER_LOGICALAND;
- slang_operation_add_children(cond, 2);
- {
- slang_operation *notBreak = slang_oper_child(cond, 0);
- slang_operation_identifier(notBreak, A, "_notBreakFlag");
- }
- {
- slang_operation *origCond = slang_oper_child(cond, 1);
- slang_operation_copy(origCond, slang_oper_child(oper, 1));
- }
- }
- }
-
- /* Finally, in innerBody,
- * replace "break" with "_notBreakFlag = 0; break"
- * replace "continue" with "break"
- */
- replace_break_and_cont(A, innerBody);
-
- /*slang_print_tree(top, 0);*/
-
- return _slang_gen_operation(A, top);
-}
-
-
-/**
- * Generate IR tree for a do-while loop using high-level LOOP, IF instructions.
- */
-static slang_ir_node *
-_slang_gen_do(slang_assemble_ctx * A, slang_operation *oper)
-{
- /*
- * LOOP:
- * body code (child[0])
- * tail code:
- * BREAK if !expr (child[1])
- */
- slang_ir_node *loop;
- GLboolean isConst, constTrue;
-
- if (!A->EmitContReturn) {
- /* We don't want to emit CONT instructions. If this do-loop has
- * a continue, translate it away.
- */
- if (_slang_loop_contains_continue(slang_oper_child(oper, 0))) {
- return _slang_gen_do_without_continue(A, oper);
- }
- }
-
- /* type-check expression */
- if (!_slang_is_boolean(A, &oper->children[1])) {
- slang_info_log_error(A->log, "scalar/boolean expression expected for 'do/while'");
- return NULL;
- }
-
- loop = new_loop(NULL);
-
- /* save loop state */
- push_loop(A, oper, loop);
-
- /* loop body: */
- loop->Children[0] = _slang_gen_operation(A, &oper->children[0]);
-
- /* Check if loop condition is a constant */
- isConst = _slang_is_constant_cond(&oper->children[1], &constTrue);
- if (isConst && constTrue) {
- /* do { } while(1) ==> no conditional break */
- loop->Children[1] = NULL; /* no tail code */
- }
- else {
- slang_ir_node *cond
- = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));
- loop->Children[1] = new_break_if_true(A, cond);
- }
-
- /* XXX we should do infinite loop detection, as above */
-
- /* restore loop state */
- pop_loop(A);
-
- return loop;
-}
-
-
-/**
- * Recursively count the number of operations rooted at 'oper'.
- * This gives some kind of indication of the size/complexity of an operation.
- */
-static GLuint
-sizeof_operation(const slang_operation *oper)
-{
- if (oper) {
- GLuint count = 1; /* me */
- GLuint i;
- for (i = 0; i < oper->num_children; i++) {
- count += sizeof_operation(&oper->children[i]);
- }
- return count;
- }
- else {
- return 0;
- }
-}
-
-
-/**
- * Determine if a for-loop can be unrolled.
- * At this time, only a rather narrow class of for loops can be unrolled.
- * See code for details.
- * When a loop can't be unrolled because it's too large we'll emit a
- * message to the log.
- */
-static GLboolean
-_slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
-{
- GLuint bodySize;
- GLint start, end;
- const char *varName;
- slang_atom varId;
-
- if (oper->type != SLANG_OPER_FOR)
- return GL_FALSE;
-
- assert(oper->num_children == 4);
-
- if (_slang_loop_contains_continue_or_break(slang_oper_child_const(oper, 3)))
- return GL_FALSE;
-
- /* children[0] must be either "int i=constant" or "i=constant" */
- if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
- slang_variable *var;
-
- if (oper->children[0].children[0].type != SLANG_OPER_VARIABLE_DECL)
- return GL_FALSE;
-
- varId = oper->children[0].children[0].a_id;
-
- var = _slang_variable_locate(oper->children[0].children[0].locals,
- varId, GL_TRUE);
- if (!var)
- return GL_FALSE;
- if (!var->initializer)
- return GL_FALSE;
- if (var->initializer->type != SLANG_OPER_LITERAL_INT)
- return GL_FALSE;
- start = (GLint) var->initializer->literal[0];
- }
- else if (oper->children[0].type == SLANG_OPER_EXPRESSION) {
- if (oper->children[0].children[0].type != SLANG_OPER_ASSIGN)
- return GL_FALSE;
- if (oper->children[0].children[0].children[0].type != SLANG_OPER_IDENTIFIER)
- return GL_FALSE;
- if (oper->children[0].children[0].children[1].type != SLANG_OPER_LITERAL_INT)
- return GL_FALSE;
-
- varId = oper->children[0].children[0].children[0].a_id;
-
- start = (GLint) oper->children[0].children[0].children[1].literal[0];
- }
- else {
- return GL_FALSE;
- }
-
- /* children[1] must be "i<constant" */
- if (oper->children[1].type != SLANG_OPER_EXPRESSION)
- return GL_FALSE;
- if (oper->children[1].children[0].type != SLANG_OPER_LESS)
- return GL_FALSE;
- if (oper->children[1].children[0].children[0].type != SLANG_OPER_IDENTIFIER)
- return GL_FALSE;
- if (oper->children[1].children[0].children[1].type != SLANG_OPER_LITERAL_INT)
- return GL_FALSE;
-
- end = (GLint) oper->children[1].children[0].children[1].literal[0];
-
- /* children[2] must be "i++" or "++i" */
- if (oper->children[2].type != SLANG_OPER_POSTINCREMENT &&
- oper->children[2].type != SLANG_OPER_PREINCREMENT)
- return GL_FALSE;
- if (oper->children[2].children[0].type != SLANG_OPER_IDENTIFIER)
- return GL_FALSE;
-
- /* make sure the same variable name is used in all places */
- if ((oper->children[1].children[0].children[0].a_id != varId) ||
- (oper->children[2].children[0].a_id != varId))
- return GL_FALSE;
-
- varName = (const char *) varId;
-
- /* children[3], the loop body, can't be too large */
- bodySize = sizeof_operation(&oper->children[3]);
- if (bodySize > MAX_FOR_LOOP_UNROLL_BODY_SIZE) {
- slang_info_log_print(A->log,
- "Note: 'for (%s ... )' body is too large/complex"
- " to unroll",
- varName);
- return GL_FALSE;
- }
-
- if (start >= end)
- return GL_FALSE; /* degenerate case */
-
- if ((GLuint)(end - start) > MAX_FOR_LOOP_UNROLL_ITERATIONS) {
- slang_info_log_print(A->log,
- "Note: 'for (%s=%d; %s<%d; ++%s)' is too"
- " many iterations to unroll",
- varName, start, varName, end, varName);
- return GL_FALSE;
- }
-
- if ((end - start) * bodySize > MAX_FOR_LOOP_UNROLL_COMPLEXITY) {
- slang_info_log_print(A->log,
- "Note: 'for (%s=%d; %s<%d; ++%s)' will generate"
- " too much code to unroll",
- varName, start, varName, end, varName);
- return GL_FALSE;
- }
-
- return GL_TRUE; /* we can unroll the loop */
-}
-
-
-/**
- * Unroll a for-loop.
- * First we determine the number of iterations to unroll.
- * Then for each iteration:
- * make a copy of the loop body
- * replace instances of the loop variable with the current iteration value
- * generate IR code for the body
- * \return pointer to generated IR code or NULL if error, out of memory, etc.
- */
-static slang_ir_node *
-_slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
-{
- GLint start, end, iter;
- slang_ir_node *n, *root = NULL;
- slang_atom varId;
-
- if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
- /* for (int i=0; ... */
- slang_variable *var;
-
- varId = oper->children[0].children[0].a_id;
- var = _slang_variable_locate(oper->children[0].children[0].locals,
- varId, GL_TRUE);
- assert(var);
- start = (GLint) var->initializer->literal[0];
- }
- else {
- /* for (i=0; ... */
- varId = oper->children[0].children[0].children[0].a_id;
- start = (GLint) oper->children[0].children[0].children[1].literal[0];
- }
-
- end = (GLint) oper->children[1].children[0].children[1].literal[0];
-
- for (iter = start; iter < end; iter++) {
- slang_operation *body;
-
- /* make a copy of the loop body */
- body = slang_operation_new(1);
- if (!body)
- return NULL;
-
- if (!slang_operation_copy(body, &oper->children[3]))
- return NULL;
-
- /* in body, replace instances of 'varId' with literal 'iter' */
- {
- slang_variable *oldVar;
- slang_operation *newOper;
-
- oldVar = _slang_variable_locate(oper->locals, varId, GL_TRUE);
- if (!oldVar) {
- /* undeclared loop variable */
- slang_operation_delete(body);
- return NULL;
- }
-
- newOper = slang_operation_new(1);
- newOper->type = SLANG_OPER_LITERAL_INT;
- newOper->literal_size = 1;
- newOper->literal[0] = (GLfloat) iter;
-
- /* replace instances of the loop variable with newOper */
- slang_substitute(A, body, 1, &oldVar, &newOper, GL_FALSE);
- }
-
- /* do IR codegen for body */
- n = _slang_gen_operation(A, body);
- if (!n)
- return NULL;
-
- root = new_seq(root, n);
-
- slang_operation_delete(body);
- }
-
- return root;
-}
-
-
-/**
- * Replace 'continue' statement with 'break' inside a for-loop.
- * This is a recursive helper function used by _slang_gen_for_without_continue().
- */
-static void
-replace_continue_with_break(slang_assemble_ctx *A, slang_operation *oper)
-{
- switch (oper->type) {
- case SLANG_OPER_CONTINUE:
- oper->type = SLANG_OPER_BREAK;
- break;
- case SLANG_OPER_FOR:
- case SLANG_OPER_DO:
- case SLANG_OPER_WHILE:
- /* stop upon finding a nested loop */
- break;
- default:
- /* recurse */
- {
- GLuint i;
- for (i = 0; i < oper->num_children; i++) {
- replace_continue_with_break(A, slang_oper_child(oper, i));
- }
- }
- }
-}
-
-
-/**
- * Transform a for-loop so that continue statements are converted to breaks.
- * Then do normal IR code generation.
- *
- * Before:
- *
- * for (INIT; LOOPCOND; INCR) {
- * A;
- * if (IFCOND) {
- * continue;
- * }
- * B;
- * }
- *
- * After:
- *
- * {
- * bool _condFlag = 1;
- * for (INIT; _condFlag; ) {
- * for ( ; _condFlag = LOOPCOND; INCR) {
- * A;
- * if (IFCOND) {
- * break;
- * }
- * B;
- * }
- * if (_condFlag)
- * INCR;
- * }
- * }
- */
-static slang_ir_node *
-_slang_gen_for_without_continue(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_operation *top;
- slang_operation *outerFor, *innerFor, *init, *cond, *incr;
- slang_operation *lhs, *rhs;
-
- assert(oper->type == SLANG_OPER_FOR);
-
- top = slang_operation_new(1);
- top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
- top->locals->outer_scope = oper->locals->outer_scope;
- slang_operation_add_children(top, 2);
-
- /* declare: bool _condFlag = true */
- {
- slang_operation *condDecl = slang_oper_child(top, 0);
- slang_generate_declaration(A, top->locals, condDecl,
- SLANG_SPEC_BOOL, "_condFlag", GL_TRUE);
- }
-
- /* build outer loop: for (INIT; _condFlag; ) { */
- outerFor = slang_oper_child(top, 1);
- outerFor->type = SLANG_OPER_FOR;
- slang_operation_add_children(outerFor, 4);
-
- init = slang_oper_child(outerFor, 0);
- slang_operation_copy(init, slang_oper_child(oper, 0));
-
- cond = slang_oper_child(outerFor, 1);
- cond->type = SLANG_OPER_IDENTIFIER;
- cond->a_id = slang_atom_pool_atom(A->atoms, "_condFlag");
-
- incr = slang_oper_child(outerFor, 2);
- incr->type = SLANG_OPER_VOID;
-
- /* body of the outer loop */
- {
- slang_operation *block = slang_oper_child(outerFor, 3);
-
- slang_operation_add_children(block, 2);
- block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
-
- /* build inner loop: for ( ; _condFlag = LOOPCOND; INCR) { */
- {
- innerFor = slang_oper_child(block, 0);
-
- /* make copy of orig loop */
- slang_operation_copy(innerFor, oper);
- assert(innerFor->type == SLANG_OPER_FOR);
- innerFor->locals->outer_scope = block->locals;
-
- init = slang_oper_child(innerFor, 0);
- init->type = SLANG_OPER_VOID; /* leak? */
-
- cond = slang_oper_child(innerFor, 1);
- slang_operation_destruct(cond);
- cond->type = SLANG_OPER_ASSIGN;
- cond->locals = _slang_variable_scope_new(innerFor->locals);
- slang_operation_add_children(cond, 2);
-
- lhs = slang_oper_child(cond, 0);
- lhs->type = SLANG_OPER_IDENTIFIER;
- lhs->a_id = slang_atom_pool_atom(A->atoms, "_condFlag");
-
- rhs = slang_oper_child(cond, 1);
- slang_operation_copy(rhs, slang_oper_child(oper, 1));
- }
-
- /* if (_condFlag) INCR; */
- {
- slang_operation *ifop = slang_oper_child(block, 1);
- ifop->type = SLANG_OPER_IF;
- slang_operation_add_children(ifop, 2);
-
- /* re-use cond node build above */
- slang_operation_copy(slang_oper_child(ifop, 0), cond);
-
- /* incr node from original for-loop operation */
- slang_operation_copy(slang_oper_child(ifop, 1),
- slang_oper_child(oper, 2));
- }
-
- /* finally, replace "continue" with "break" in the inner for-loop */
- replace_continue_with_break(A, slang_oper_child(innerFor, 3));
- }
-
- return _slang_gen_operation(A, top);
-}
-
-
-
-/**
- * Generate IR for a for-loop. Unrolling will be done when possible.
- */
-static slang_ir_node *
-_slang_gen_for(slang_assemble_ctx * A, slang_operation *oper)
-{
- GLboolean unroll;
-
- if (!A->EmitContReturn) {
- /* We don't want to emit CONT instructions. If this for-loop has
- * a continue, translate it away.
- */
- if (_slang_loop_contains_continue(slang_oper_child(oper, 3))) {
- return _slang_gen_for_without_continue(A, oper);
- }
- }
-
- unroll = _slang_can_unroll_for_loop(A, oper);
- if (unroll) {
- slang_ir_node *code = _slang_unroll_for_loop(A, oper);
- if (code)
- return code;
- }
-
- assert(oper->type == SLANG_OPER_FOR);
-
- /* conventional for-loop code generation */
- {
- /*
- * init code (child[0])
- * LOOP:
- * BREAK if !expr (child[1])
- * body code (child[3])
- * tail code:
- * incr code (child[2]) // XXX continue here
- */
- slang_ir_node *loop, *cond, *breakIf, *body, *init, *incr;
- init = _slang_gen_operation(A, &oper->children[0]);
- loop = new_loop(NULL);
-
- /* save loop state */
- push_loop(A, oper, loop);
-
- cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));
- breakIf = new_break_if_true(A, cond);
- body = _slang_gen_operation(A, &oper->children[3]);
- incr = _slang_gen_operation(A, &oper->children[2]);
-
- loop->Children[0] = new_seq(breakIf, body);
- loop->Children[1] = incr; /* tail code */
-
- /* restore loop state */
- pop_loop(A);
-
- return new_seq(init, loop);
- }
-}
-
-
-static slang_ir_node *
-_slang_gen_continue(slang_assemble_ctx * A, const slang_operation *oper)
-{
- slang_ir_node *n, *cont, *incr = NULL, *loopNode;
-
- assert(oper->type == SLANG_OPER_CONTINUE);
- loopNode = current_loop_ir(A);
- assert(loopNode);
- assert(loopNode->Opcode == IR_LOOP);
-
- cont = new_node0(IR_CONT);
- if (cont) {
- cont->Parent = loopNode;
- /* insert this node at head of linked list of cont/break instructions */
- cont->List = loopNode->List;
- loopNode->List = cont;
- }
-
- n = new_seq(incr, cont);
- return n;
-}
-
-
-/**
- * Determine if the given operation is of a specific type.
- */
-static GLboolean
-is_operation_type(const slang_operation *oper, slang_operation_type type)
-{
- if (oper->type == type)
- return GL_TRUE;
- else if ((oper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
- oper->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) &&
- oper->num_children == 1)
- return is_operation_type(&oper->children[0], type);
- else
- return GL_FALSE;
-}
-
-
-/**
- * Generate IR tree for an if/then/else conditional using high-level
- * IR_IF instruction.
- */
-static slang_ir_node *
-_slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
-{
- /*
- * eval expr (child[0])
- * IF expr THEN
- * if-body code
- * ELSE
- * else-body code
- * ENDIF
- */
- const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]);
- slang_ir_node *ifNode, *cond, *ifBody, *elseBody;
- GLboolean isConst, constTrue;
-
- /* type-check expression */
- if (!_slang_is_boolean(A, &oper->children[0])) {
- slang_info_log_error(A->log, "boolean expression expected for 'if'");
- return NULL;
- }
-
- if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) {
- slang_info_log_error(A->log, "scalar/boolean expression expected for 'if'");
- return NULL;
- }
-
- isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);
- if (isConst) {
- if (constTrue) {
- /* if (true) ... */
- return _slang_gen_operation(A, &oper->children[1]);
- }
- else {
- /* if (false) ... */
- return _slang_gen_operation(A, &oper->children[2]);
- }
- }
-
- cond = _slang_gen_operation(A, &oper->children[0]);
- cond = new_cond(cond);
-
- if (is_operation_type(&oper->children[1], SLANG_OPER_BREAK)
- && !haveElseClause) {
- /* Special case: generate a conditional break */
- ifBody = new_break_if_true(A, cond);
- return ifBody;
- }
- else if (is_operation_type(&oper->children[1], SLANG_OPER_CONTINUE)
- && !haveElseClause
- && current_loop_oper(A)
- && current_loop_oper(A)->type != SLANG_OPER_FOR) {
- /* Special case: generate a conditional continue */
- ifBody = new_cont_if_true(A, cond);
- return ifBody;
- }
- else {
- /* general case */
- ifBody = _slang_gen_operation(A, &oper->children[1]);
- if (haveElseClause)
- elseBody = _slang_gen_operation(A, &oper->children[2]);
- else
- elseBody = NULL;
- ifNode = new_if(cond, ifBody, elseBody);
- return ifNode;
- }
-}
-
-
-
-static slang_ir_node *
-_slang_gen_not(slang_assemble_ctx * A, const slang_operation *oper)
-{
- slang_ir_node *n;
-
- assert(oper->type == SLANG_OPER_NOT);
-
- /* type-check expression */
- if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) {
- slang_info_log_error(A->log,
- "scalar/boolean expression expected for '!'");
- return NULL;
- }
-
- n = _slang_gen_operation(A, &oper->children[0]);
- if (n)
- return new_not(n);
- else
- return NULL;
-}
-
-
-static slang_ir_node *
-_slang_gen_xor(slang_assemble_ctx * A, const slang_operation *oper)
-{
- slang_ir_node *n1, *n2;
-
- assert(oper->type == SLANG_OPER_LOGICALXOR);
-
- if (!_slang_is_scalar_or_boolean(A, &oper->children[0]) ||
- !_slang_is_scalar_or_boolean(A, &oper->children[0])) {
- slang_info_log_error(A->log,
- "scalar/boolean expressions expected for '^^'");
- return NULL;
- }
-
- n1 = _slang_gen_operation(A, &oper->children[0]);
- if (!n1)
- return NULL;
- n2 = _slang_gen_operation(A, &oper->children[1]);
- if (!n2)
- return NULL;
- return new_node2(IR_NOTEQUAL, n1, n2);
-}
-
-
-/**
- * Generate IR node for storage of a temporary of given size.
- */
-static slang_ir_node *
-_slang_gen_temporary(GLint size)
-{
- slang_ir_storage *store;
- slang_ir_node *n = NULL;
-
- store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -2, size);
- if (store) {
- n = new_node0(IR_VAR_DECL);
- if (n) {
- n->Store = store;
- }
- else {
- _slang_free(store);
- }
- }
- return n;
-}
-
-
-/**
- * Generate program constants for an array.
- * Ex: const vec2[3] v = vec2[3](vec2(1,1), vec2(2,2), vec2(3,3));
- * This will allocate and initialize three vector constants, storing
- * the array in constant memory, not temporaries like a non-const array.
- * This can also be used for uniform array initializers.
- * \return GL_TRUE for success, GL_FALSE if failure (semantic error, etc).
- */
-static GLboolean
-make_constant_array(slang_assemble_ctx *A,
- slang_variable *var,
- slang_operation *initializer)
-{
- struct gl_program *prog = A->program;
- const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
- const char *varName = (char *) var->a_name;
- const GLuint numElements = initializer->num_children;
- GLint size;
- GLuint i, j;
- GLfloat *values;
-
- if (!var->store) {
- var->store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -6, -6);
- }
- size = var->store->Size;
-
- assert(var->type.qualifier == SLANG_QUAL_CONST ||
- var->type.qualifier == SLANG_QUAL_UNIFORM);
- assert(initializer->type == SLANG_OPER_CALL);
- assert(initializer->array_constructor);
-
- values = (GLfloat *) malloc(numElements * 4 * sizeof(GLfloat));
-
- /* convert constructor params into ordinary floats */
- for (i = 0; i < numElements; i++) {
- const slang_operation *op = &initializer->children[i];
- if (op->type != SLANG_OPER_LITERAL_FLOAT) {
- /* unsupported type for this optimization */
- free(values);
- return GL_FALSE;
- }
- for (j = 0; j < op->literal_size; j++) {
- values[i * 4 + j] = op->literal[j];
- }
- for ( ; j < 4; j++) {
- values[i * 4 + j] = 0.0f;
- }
- }
-
- /* slightly different paths for constants vs. uniforms */
- if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
- var->store->File = PROGRAM_UNIFORM;
- var->store->Index = _mesa_add_uniform(prog->Parameters, varName,
- size, datatype, values);
- }
- else {
- var->store->File = PROGRAM_CONSTANT;
- var->store->Index = _mesa_add_named_constant(prog->Parameters, varName,
- values, size);
- }
- assert(var->store->Size == size);
-
- free(values);
-
- return GL_TRUE;
-}
-
-
-
-/**
- * Generate IR node for allocating/declaring a variable (either a local or
- * a global).
- * Generally, this involves allocating an slang_ir_storage instance for the
- * variable, choosing a register file (temporary, constant, etc).
- * For ordinary variables we do not yet allocate storage though. We do that
- * when we find the first actual use of the variable to avoid allocating temp
- * regs that will never get used.
- * At this time, uniforms are always allocated space in this function.
- *
- * \param initializer Optional initializer expression for the variable.
- */
-static slang_ir_node *
-_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var,
- slang_operation *initializer)
-{
- const char *varName = (const char *) var->a_name;
- const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
- slang_ir_node *varDecl, *n;
- slang_ir_storage *store;
- GLint arrayLen, size, totalSize; /* if array then totalSize > size */
- gl_register_file file;
-
- /*assert(!var->declared);*/
- var->declared = GL_TRUE;
-
- /* determine GPU register file for simple cases */
- if (is_sampler_type(&var->type)) {
- file = PROGRAM_SAMPLER;
- }
- else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
- file = PROGRAM_UNIFORM;
- }
- else {
- file = PROGRAM_TEMPORARY;
- }
-
- size = _slang_sizeof_type_specifier(&var->type.specifier);
- if (size <= 0) {
- slang_info_log_error(A->log, "invalid declaration for '%s'", varName);
- return NULL;
- }
-
- arrayLen = _slang_array_length(var);
- totalSize = _slang_array_size(size, arrayLen);
-
- /* Allocate IR node for the declaration */
- varDecl = new_node0(IR_VAR_DECL);
- if (!varDecl)
- return NULL;
-
- /* Allocate slang_ir_storage for this variable if needed.
- * Note that we may not actually allocate a constant or temporary register
- * until later.
- */
- if (!var->store) {
- GLint index = -7; /* TBD / unknown */
- var->store = _slang_new_ir_storage(file, index, totalSize);
- if (!var->store)
- return NULL; /* out of memory */
- }
-
- /* set the IR node's Var and Store pointers */
- varDecl->Var = var;
- varDecl->Store = var->store;
-
-
- store = var->store;
-
- /* if there's an initializer, generate IR for the expression */
- if (initializer) {
- slang_ir_node *varRef, *init;
-
- if (var->type.qualifier == SLANG_QUAL_CONST) {
- /* if the variable is const, the initializer must be a const
- * expression as well.
- */
-#if 0
- if (!_slang_is_constant_expr(initializer)) {
- slang_info_log_error(A->log,
- "initializer for %s not constant", varName);
- return NULL;
- }
-#endif
- }
-
- if (var->type.qualifier == SLANG_QUAL_UNIFORM &&
- !A->allow_uniform_initializers) {
- slang_info_log_error(A->log,
- "initializer for uniform %s not allowed",
- varName);
- return NULL;
- }
-
- /* IR for the variable we're initializing */
- varRef = new_var(A, var);
- if (!varRef) {
- slang_info_log_error(A->log, "out of memory");
- return NULL;
- }
-
- /* constant-folding, etc here */
- _slang_simplify(initializer, &A->space, A->atoms);
-
- /* look for simple constant-valued variables and uniforms */
- if (var->type.qualifier == SLANG_QUAL_CONST ||
- var->type.qualifier == SLANG_QUAL_UNIFORM) {
-
- if (initializer->type == SLANG_OPER_CALL &&
- initializer->array_constructor) {
- /* array initializer */
- if (make_constant_array(A, var, initializer))
- return varRef;
- }
- else if (initializer->type == SLANG_OPER_LITERAL_FLOAT ||
- initializer->type == SLANG_OPER_LITERAL_INT) {
- /* simple float/vector initializer */
- if (store->File == PROGRAM_UNIFORM) {
- store->Index = _mesa_add_uniform(A->program->Parameters,
- varName,
- totalSize, datatype,
- initializer->literal);
- store->Swizzle = _slang_var_swizzle(size, 0);
- return varRef;
- }
-#if 0
- else {
- store->File = PROGRAM_CONSTANT;
- store->Index = _mesa_add_named_constant(A->program->Parameters,
- varName,
- initializer->literal,
- totalSize);
- store->Swizzle = _slang_var_swizzle(size, 0);
- return varRef;
- }
-#endif
- }
- }
-
- /* IR for initializer */
- init = _slang_gen_operation(A, initializer);
- if (!init)
- return NULL;
-
- /* XXX remove this when type checking is added above */
- if (init->Store && init->Store->Size != totalSize) {
- slang_info_log_error(A->log, "invalid assignment (wrong types)");
- return NULL;
- }
-
- /* assign RHS to LHS */
- n = new_node2(IR_COPY, varRef, init);
- n = new_seq(varDecl, n);
- }
- else {
- /* no initializer */
- n = varDecl;
- }
-
- if (store->File == PROGRAM_UNIFORM && store->Index < 0) {
- /* always need to allocate storage for uniforms at this point */
- store->Index = _mesa_add_uniform(A->program->Parameters, varName,
- totalSize, datatype, NULL);
- store->Swizzle = _slang_var_swizzle(size, 0);
- }
-
-#if 0
- printf("%s var %p %s store=%p index=%d size=%d\n",
- __FUNCTION__, (void *) var, (char *) varName,
- (void *) store, store->Index, store->Size);
-#endif
-
- return n;
-}
-
-
-/**
- * Generate code for a selection expression: b ? x : y
- * XXX In some cases we could implement a selection expression
- * with an LRP instruction (use the boolean as the interpolant).
- * Otherwise, we use an IF/ELSE/ENDIF construct.
- */
-static slang_ir_node *
-_slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)
-{
- slang_ir_node *cond, *ifNode, *trueExpr, *falseExpr, *trueNode, *falseNode;
- slang_ir_node *tmpDecl, *tmpVar, *tree;
- slang_typeinfo type0, type1, type2;
- int size, isBool, isEqual;
-
- assert(oper->type == SLANG_OPER_SELECT);
- assert(oper->num_children == 3);
-
- /* type of children[0] must be boolean */
- slang_typeinfo_construct(&type0);
- typeof_operation(A, &oper->children[0], &type0);
- isBool = (type0.spec.type == SLANG_SPEC_BOOL);
- slang_typeinfo_destruct(&type0);
- if (!isBool) {
- slang_info_log_error(A->log, "selector type is not boolean");
- return NULL;
- }
-
- slang_typeinfo_construct(&type1);
- slang_typeinfo_construct(&type2);
- typeof_operation(A, &oper->children[1], &type1);
- typeof_operation(A, &oper->children[2], &type2);
- isEqual = slang_type_specifier_equal(&type1.spec, &type2.spec);
- slang_typeinfo_destruct(&type1);
- slang_typeinfo_destruct(&type2);
- if (!isEqual) {
- slang_info_log_error(A->log, "incompatible types for ?: operator");
- return NULL;
- }
-
- /* size of x or y's type */
- size = _slang_sizeof_type_specifier(&type1.spec);
- assert(size > 0);
-
- /* temporary var */
- tmpDecl = _slang_gen_temporary(size);
-
- /* the condition (child 0) */
- cond = _slang_gen_operation(A, &oper->children[0]);
- cond = new_cond(cond);
-
- /* if-true body (child 1) */
- tmpVar = new_node0(IR_VAR);
- tmpVar->Store = tmpDecl->Store;
- trueExpr = _slang_gen_operation(A, &oper->children[1]);
- trueNode = new_node2(IR_COPY, tmpVar, trueExpr);
-
- /* if-false body (child 2) */
- tmpVar = new_node0(IR_VAR);
- tmpVar->Store = tmpDecl->Store;
- falseExpr = _slang_gen_operation(A, &oper->children[2]);
- falseNode = new_node2(IR_COPY, tmpVar, falseExpr);
-
- ifNode = new_if(cond, trueNode, falseNode);
-
- /* tmp var value */
- tmpVar = new_node0(IR_VAR);
- tmpVar->Store = tmpDecl->Store;
-
- tree = new_seq(ifNode, tmpVar);
- tree = new_seq(tmpDecl, tree);
-
- /*_slang_print_ir_tree(tree, 10);*/
- return tree;
-}
-
-
-/**
- * Generate code for &&.
- */
-static slang_ir_node *
-_slang_gen_logical_and(slang_assemble_ctx *A, slang_operation *oper)
-{
- /* rewrite "a && b" as "a ? b : false" */
- slang_operation *select;
- slang_ir_node *n;
-
- select = slang_operation_new(1);
- select->type = SLANG_OPER_SELECT;
- slang_operation_add_children(select, 3);
-
- slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]);
- slang_operation_copy(slang_oper_child(select, 1), &oper->children[1]);
- slang_operation_literal_bool(slang_oper_child(select, 2), GL_FALSE);
-
- n = _slang_gen_select(A, select);
- return n;
-}
-
-
-/**
- * Generate code for ||.
- */
-static slang_ir_node *
-_slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper)
-{
- /* rewrite "a || b" as "a ? true : b" */
- slang_operation *select;
- slang_ir_node *n;
-
- select = slang_operation_new(1);
- select->type = SLANG_OPER_SELECT;
- slang_operation_add_children(select, 3);
-
- slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]);
- slang_operation_literal_bool(slang_oper_child(select, 1), GL_TRUE);
- slang_operation_copy(slang_oper_child(select, 2), &oper->children[1]);
-
- n = _slang_gen_select(A, select);
- return n;
-}
-
-
-/**
- * Generate IR tree for a return statement.
- */
-static slang_ir_node *
-_slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
-{
- assert(oper->type == SLANG_OPER_RETURN);
- return new_return(A->curFuncEndLabel);
-}
-
-
-#if 0
-/**
- * Determine if the given operation/expression is const-valued.
- */
-static GLboolean
-_slang_is_constant_expr(const slang_operation *oper)
-{
- slang_variable *var;
- GLuint i;
-
- switch (oper->type) {
- case SLANG_OPER_IDENTIFIER:
- var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
- if (var && var->type.qualifier == SLANG_QUAL_CONST)
- return GL_TRUE;
- return GL_FALSE;
- default:
- for (i = 0; i < oper->num_children; i++) {
- if (!_slang_is_constant_expr(&oper->children[i]))
- return GL_FALSE;
- }
- return GL_TRUE;
- }
-}
-#endif
-
-
-/**
- * Check if an assignment of type t1 to t0 is legal.
- * XXX more cases needed.
- */
-static GLboolean
-_slang_assignment_compatible(slang_assemble_ctx *A,
- slang_operation *op0,
- slang_operation *op1)
-{
- slang_typeinfo t0, t1;
- GLuint sz0, sz1;
-
- if (op0->type == SLANG_OPER_POSTINCREMENT ||
- op0->type == SLANG_OPER_POSTDECREMENT) {
- return GL_FALSE;
- }
-
- slang_typeinfo_construct(&t0);
- typeof_operation(A, op0, &t0);
-
- slang_typeinfo_construct(&t1);
- typeof_operation(A, op1, &t1);
-
- sz0 = _slang_sizeof_type_specifier(&t0.spec);
- sz1 = _slang_sizeof_type_specifier(&t1.spec);
-
-#if 1
- if (sz0 != sz1) {
- /*printf("assignment size mismatch %u vs %u\n", sz0, sz1);*/
- return GL_FALSE;
- }
-#endif
-
- if (t0.spec.type == SLANG_SPEC_STRUCT &&
- t1.spec.type == SLANG_SPEC_STRUCT &&
- t0.spec._struct->a_name != t1.spec._struct->a_name)
- return GL_FALSE;
-
- if (t0.spec.type == SLANG_SPEC_FLOAT &&
- t1.spec.type == SLANG_SPEC_BOOL)
- return GL_FALSE;
-
-#if 0 /* not used just yet - causes problems elsewhere */
- if (t0.spec.type == SLANG_SPEC_INT &&
- t1.spec.type == SLANG_SPEC_FLOAT)
- return GL_FALSE;
-#endif
-
- if (t0.spec.type == SLANG_SPEC_BOOL &&
- t1.spec.type == SLANG_SPEC_FLOAT)
- return GL_FALSE;
-
- if (t0.spec.type == SLANG_SPEC_BOOL &&
- t1.spec.type == SLANG_SPEC_INT)
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-
-/**
- * Generate IR tree for a local variable declaration.
- * Basically do some error checking and call _slang_gen_var_decl().
- */
-static slang_ir_node *
-_slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
-{
- const char *varName = (char *) oper->a_id;
- slang_variable *var;
- slang_ir_node *varDecl;
- slang_operation *initializer;
-
- assert(oper->type == SLANG_OPER_VARIABLE_DECL);
- assert(oper->num_children <= 1);
-
-
- /* lookup the variable by name */
- var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
- if (!var)
- return NULL; /* "shouldn't happen" */
-
- if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE ||
- var->type.qualifier == SLANG_QUAL_VARYING ||
- var->type.qualifier == SLANG_QUAL_UNIFORM) {
- /* can't declare attribute/uniform vars inside functions */
- slang_info_log_error(A->log,
- "local variable '%s' cannot be an attribute/uniform/varying",
- varName);
- return NULL;
- }
-
-#if 0
- if (v->declared) {
- slang_info_log_error(A->log, "variable '%s' redeclared", varName);
- return NULL;
- }
-#endif
-
- /* check if the var has an initializer */
- if (oper->num_children > 0) {
- assert(oper->num_children == 1);
- initializer = &oper->children[0];
- }
- else if (var->initializer) {
- initializer = var->initializer;
- }
- else {
- initializer = NULL;
- }
-
- if (initializer) {
- /* check/compare var type and initializer type */
- if (!_slang_assignment_compatible(A, oper, initializer)) {
- slang_info_log_error(A->log, "incompatible types in assignment");
- return NULL;
- }
- }
- else {
- if (var->type.qualifier == SLANG_QUAL_CONST) {
- slang_info_log_error(A->log,
- "const-qualified variable '%s' requires initializer",
- varName);
- return NULL;
- }
- }
-
- /* Generate IR node */
- varDecl = _slang_gen_var_decl(A, var, initializer);
- if (!varDecl)
- return NULL;
-
- return varDecl;
-}
-
-
-/**
- * Generate IR tree for a reference to a variable (such as in an expression).
- * This is different from a variable declaration.
- */
-static slang_ir_node *
-_slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper)
-{
- /* If there's a variable associated with this oper (from inlining)
- * use it. Otherwise, use the oper's var id.
- */
- slang_atom name = oper->var ? oper->var->a_name : oper->a_id;
- slang_variable *var = _slang_variable_locate(oper->locals, name, GL_TRUE);
- slang_ir_node *n;
- if (!var || !var->declared) {
- /* Geometry shaders set gl_VerticesIn at link time
- * so we need to wait with resolving this variable
- * until then */
- if (A->program->Target == MESA_GEOMETRY_PROGRAM &&
- !strcmp((char*)name, "gl_VerticesIn") ){
- A->UnresolvedRefs = GL_TRUE;
- return NULL;
- }
- slang_info_log_error(A->log, "undefined variable '%s'", (char *) name);
- return NULL;
- }
- n = new_var(A, var);
- return n;
-}
-
-
-
-/**
- * Return the number of components actually named by the swizzle.
- * Recall that swizzles may have undefined/don't-care values.
- */
-static GLuint
-swizzle_size(GLuint swizzle)
-{
- GLuint size = 0, i;
- for (i = 0; i < 4; i++) {
- GLuint swz = GET_SWZ(swizzle, i);
- size += (swz <= 3);
- }
- return size;
-}
-
-
-static slang_ir_node *
-_slang_gen_swizzle(slang_ir_node *child, GLuint swizzle)
-{
- slang_ir_node *n = new_node1(IR_SWIZZLE, child);
- assert(child);
- if (n) {
- assert(!n->Store);
- n->Store = _slang_new_ir_storage_relative(0,
- swizzle_size(swizzle),
- child->Store);
- assert(n->Store);
- n->Store->Swizzle = swizzle;
- }
- return n;
-}
-
-
-static GLboolean
-is_store_writable(const slang_assemble_ctx *A, const slang_ir_storage *store)
-{
- while (store->Parent)
- store = store->Parent;
-
- if (!(store->File == PROGRAM_OUTPUT ||
- store->File == PROGRAM_TEMPORARY ||
- (store->File == PROGRAM_VARYING &&
- (A->program->Target == GL_VERTEX_PROGRAM_ARB ||
- A->program->Target == MESA_GEOMETRY_PROGRAM)))) {
- return GL_FALSE;
- }
- else {
- return GL_TRUE;
- }
-}
-
-
-/**
- * Walk up an IR storage path to compute the final swizzle.
- * This is used when we find an expression such as "foo.xz.yx".
- */
-static GLuint
-root_swizzle(const slang_ir_storage *st)
-{
- GLuint swizzle = st->Swizzle;
- while (st->Parent) {
- st = st->Parent;
- swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle);
- }
- return swizzle;
-}
-
-
-/**
- * Generate IR tree for an assignment (=).
- */
-static slang_ir_node *
-_slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
-{
- slang_operation *pred = NULL;
- slang_ir_node *n = NULL;
-
- if (oper->children[0].type == SLANG_OPER_IDENTIFIER) {
- /* Check that var is writeable */
- const char *varName = (char *) oper->children[0].a_id;
- slang_variable *var
- = _slang_variable_locate(oper->children[0].locals,
- oper->children[0].a_id, GL_TRUE);
- if (!var) {
- slang_info_log_error(A->log, "undefined variable '%s'", varName);
- return NULL;
- }
-
- if (var->type.qualifier == SLANG_QUAL_CONST ||
- var->type.qualifier == SLANG_QUAL_ATTRIBUTE ||
- var->type.qualifier == SLANG_QUAL_UNIFORM ||
- (var->type.qualifier == SLANG_QUAL_VARYING &&
- A->program->Target == GL_FRAGMENT_PROGRAM_ARB)) {
- slang_info_log_error(A->log,
- "illegal assignment to read-only variable '%s'",
- varName);
- return NULL;
- }
-
- /* check if we need to predicate this assignment based on __notRetFlag */
- if ((var->is_global ||
- var->type.qualifier == SLANG_QUAL_OUT ||
- var->type.qualifier == SLANG_QUAL_INOUT) && A->UseReturnFlag) {
- /* create predicate, used below */
- pred = slang_operation_new(1);
- pred->type = SLANG_OPER_IDENTIFIER;
- pred->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
- pred->locals->outer_scope = oper->locals->outer_scope;
- }
- }
-
- if (oper->children[0].type == SLANG_OPER_IDENTIFIER &&
- oper->children[1].type == SLANG_OPER_CALL) {
- /* Special case of: x = f(a, b)
- * Replace with f(a, b, x) (where x == hidden __retVal out param)
- *
- * XXX this could be even more effective if we could accomodate
- * cases such as "v.x = f();" - would help with typical vertex
- * transformation.
- */
- n = _slang_gen_function_call_name(A,
- (const char *) oper->children[1].a_id,
- &oper->children[1], &oper->children[0]);
- }
- else {
- slang_ir_node *lhs, *rhs;
-
- /* lhs and rhs type checking */
- if (!_slang_assignment_compatible(A,
- &oper->children[0],
- &oper->children[1])) {
- slang_info_log_error(A->log, "incompatible types in assignment");
- return NULL;
- }
-
- lhs = _slang_gen_operation(A, &oper->children[0]);
- if (!lhs) {
- return NULL;
- }
-
- if (!lhs->Store) {
- slang_info_log_error(A->log,
- "invalid left hand side for assignment");
- return NULL;
- }
-
- /* check that lhs is writable */
- if (!is_store_writable(A, lhs->Store)) {
- slang_info_log_error(A->log,
- "illegal assignment to read-only l-value");
- return NULL;
- }
-
- rhs = _slang_gen_operation(A, &oper->children[1]);
- if (lhs && rhs) {
- /* convert lhs swizzle into writemask */
- const GLuint swizzle = root_swizzle(lhs->Store);
- GLuint writemask, newSwizzle = 0x0;
- if (!swizzle_to_writemask(A, swizzle, &writemask, &newSwizzle)) {
- /* Non-simple writemask, need to swizzle right hand side in
- * order to put components into the right place.
- */
- rhs = _slang_gen_swizzle(rhs, newSwizzle);
- }
- n = new_node2(IR_COPY, lhs, rhs);
- }
- else {
- return NULL;
- }
- }
-
- if (n && pred) {
- /* predicate the assignment code on __notRetFlag */
- slang_ir_node *top, *cond;
-
- cond = _slang_gen_operation(A, pred);
- top = new_if(cond, n, NULL);
- return top;
- }
- return n;
-}
-
-
-/**
- * Generate IR tree for referencing a field in a struct (or basic vector type)
- */
-static slang_ir_node *
-_slang_gen_struct_field(slang_assemble_ctx * A, slang_operation *oper)
-{
- slang_typeinfo ti;
-
- /* type of struct */
- slang_typeinfo_construct(&ti);
- typeof_operation(A, &oper->children[0], &ti);
-
- if (_slang_type_is_vector(ti.spec.type)) {
- /* the field should be a swizzle */
- const GLuint rows = _slang_type_dim(ti.spec.type);
- slang_swizzle swz;
- slang_ir_node *n;
- GLuint swizzle;
- if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
- slang_info_log_error(A->log, "Bad swizzle");
- return NULL;
- }
- swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
- swz.swizzle[1],
- swz.swizzle[2],
- swz.swizzle[3]);
-
- n = _slang_gen_operation(A, &oper->children[0]);
- /* create new parent node with swizzle */
- if (n)
- n = _slang_gen_swizzle(n, swizzle);
- return n;
- }
- else if ( ti.spec.type == SLANG_SPEC_FLOAT
- || ti.spec.type == SLANG_SPEC_INT
- || ti.spec.type == SLANG_SPEC_BOOL) {
- const GLuint rows = 1;
- slang_swizzle swz;
- slang_ir_node *n;
- GLuint swizzle;
- if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
- slang_info_log_error(A->log, "Bad swizzle");
- }
- swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
- swz.swizzle[1],
- swz.swizzle[2],
- swz.swizzle[3]);
- n = _slang_gen_operation(A, &oper->children[0]);
- /* create new parent node with swizzle */
- n = _slang_gen_swizzle(n, swizzle);
- return n;
- }
- else {
- /* the field is a structure member (base.field) */
- /* oper->children[0] is the base */
- /* oper->a_id is the field name */
- slang_ir_node *base, *n;
- slang_typeinfo field_ti;
- GLint fieldSize, fieldOffset = -1;
-
- /* type of field */
- slang_typeinfo_construct(&field_ti);
- typeof_operation(A, oper, &field_ti);
-
- fieldSize = _slang_sizeof_type_specifier(&field_ti.spec);
- if (fieldSize > 0)
- fieldOffset = _slang_field_offset(&ti.spec, oper->a_id);
-
- if (fieldSize == 0 || fieldOffset < 0) {
- const char *structName;
- if (ti.spec._struct)
- structName = (char *) ti.spec._struct->a_name;
- else
- structName = "unknown";
- slang_info_log_error(A->log,
- "\"%s\" is not a member of struct \"%s\"",
- (char *) oper->a_id, structName);
- return NULL;
- }
- assert(fieldSize >= 0);
-
- base = _slang_gen_operation(A, &oper->children[0]);
- if (!base) {
- /* error msg should have already been logged */
- return NULL;
- }
-
- n = new_node1(IR_FIELD, base);
- if (!n)
- return NULL;
-
- n->Field = (char *) oper->a_id;
-
- /* Store the field's offset in storage->Index */
- n->Store = _slang_new_ir_storage(base->Store->File,
- fieldOffset,
- fieldSize);
-
- return n;
- }
-}
-
-
-/**
- * Gen code for array indexing.
- */
-static slang_ir_node *
-_slang_gen_array_element(slang_assemble_ctx * A, slang_operation *oper)
-{
- slang_typeinfo array_ti;
-
- /* get array's type info */
- slang_typeinfo_construct(&array_ti);
- typeof_operation(A, &oper->children[0], &array_ti);
-
- if (_slang_type_is_vector(array_ti.spec.type)) {
- /* indexing a simple vector type: "vec4 v; v[0]=p;" */
- /* translate the index into a swizzle/writemask: "v.x=p" */
- const GLuint max = _slang_type_dim(array_ti.spec.type);
- GLint index;
- slang_ir_node *n;
-
- index = (GLint) oper->children[1].literal[0];
- if (oper->children[1].type != SLANG_OPER_LITERAL_INT ||
- index >= (GLint) max) {
-#if 0
- slang_info_log_error(A->log, "Invalid array index for vector type");
- printf("type = %d\n", oper->children[1].type);
- printf("index = %d, max = %d\n", index, max);
- printf("array = %s\n", (char*)oper->children[0].a_id);
- printf("index = %s\n", (char*)oper->children[1].a_id);
- return NULL;
-#else
- index = 0;
-#endif
- }
-
- n = _slang_gen_operation(A, &oper->children[0]);
- if (n) {
- /* use swizzle to access the element */
- GLuint swizzle = MAKE_SWIZZLE4(SWIZZLE_X + index,
- SWIZZLE_NIL,
- SWIZZLE_NIL,
- SWIZZLE_NIL);
- n = _slang_gen_swizzle(n, swizzle);
- }
- return n;
- }
- else {
- /* conventional array */
- slang_typeinfo elem_ti;
- slang_ir_node *elem, *array, *index;
- GLint elemSize, arrayLen;
-
- /* size of array element */
- slang_typeinfo_construct(&elem_ti);
- typeof_operation(A, oper, &elem_ti);
- elemSize = _slang_sizeof_type_specifier(&elem_ti.spec);
-
- if (_slang_type_is_matrix(array_ti.spec.type))
- arrayLen = _slang_type_dim(array_ti.spec.type);
- else
- arrayLen = array_ti.array_len;
-
- slang_typeinfo_destruct(&array_ti);
- slang_typeinfo_destruct(&elem_ti);
-
- if (elemSize <= 0) {
- /* unknown var or type */
- slang_info_log_error(A->log, "Undefined variable or type");
- return NULL;
- }
-
- array = _slang_gen_operation(A, &oper->children[0]);
- index = _slang_gen_operation(A, &oper->children[1]);
- if (array && index) {
- /* bounds check */
- GLint constIndex = -1;
- if (index->Opcode == IR_FLOAT) {
- constIndex = (int) index->Value[0];
- if (constIndex < 0 || constIndex >= arrayLen) {
- slang_info_log_error(A->log,
- "Array index out of bounds (index=%d size=%d)",
- constIndex, arrayLen);
- _slang_free_ir_tree(array);
- _slang_free_ir_tree(index);
- return NULL;
- }
- }
-
- if (!array->Store) {
- slang_info_log_error(A->log, "Invalid array");
- return NULL;
- }
-
- elem = new_node2(IR_ELEMENT, array, index);
-
- /* The storage info here will be updated during code emit */
- elem->Store = _slang_new_ir_storage(array->Store->File,
- array->Store->Index,
- elemSize);
- elem->Store->Swizzle = _slang_var_swizzle(elemSize, 0);
- return elem;
- }
- else {
- _slang_free_ir_tree(array);
- _slang_free_ir_tree(index);
- return NULL;
- }
- }
-}
-
-
-static slang_ir_node *
-_slang_gen_compare(slang_assemble_ctx *A, slang_operation *oper,
- slang_ir_opcode opcode)
-{
- slang_typeinfo t0, t1;
- slang_ir_node *n;
-
- slang_typeinfo_construct(&t0);
- typeof_operation(A, &oper->children[0], &t0);
-
- slang_typeinfo_construct(&t1);
- typeof_operation(A, &oper->children[0], &t1);
-
- if (t0.spec.type == SLANG_SPEC_ARRAY ||
- t1.spec.type == SLANG_SPEC_ARRAY) {
- slang_info_log_error(A->log, "Illegal array comparison");
- return NULL;
- }
-
- if (oper->type != SLANG_OPER_EQUAL &&
- oper->type != SLANG_OPER_NOTEQUAL) {
- /* <, <=, >, >= can only be used with scalars */
- if ((t0.spec.type != SLANG_SPEC_INT &&
- t0.spec.type != SLANG_SPEC_FLOAT) ||
- (t1.spec.type != SLANG_SPEC_INT &&
- t1.spec.type != SLANG_SPEC_FLOAT)) {
- slang_info_log_error(A->log, "Incompatible type(s) for inequality operator");
- return NULL;
- }
- }
-
- n = new_node2(opcode,
- _slang_gen_operation(A, &oper->children[0]),
- _slang_gen_operation(A, &oper->children[1]));
-
- /* result is a bool (size 1) */
- n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
-
- return n;
-}
-
-
-#if 0
-static void
-print_vars(slang_variable_scope *s)
-{
- int i;
- printf("vars: ");
- for (i = 0; i < s->num_variables; i++) {
- printf("%s %d, \n",
- (char*) s->variables[i]->a_name,
- s->variables[i]->declared);
- }
-
- printf("\n");
-}
-#endif
-
-
-#if 0
-static void
-_slang_undeclare_vars(slang_variable_scope *locals)
-{
- if (locals->num_variables > 0) {
- int i;
- for (i = 0; i < locals->num_variables; i++) {
- slang_variable *v = locals->variables[i];
- printf("undeclare %s at %p\n", (char*) v->a_name, v);
- v->declared = GL_FALSE;
- }
- }
-}
-#endif
-
-
-/**
- * Generate IR tree for a slang_operation (AST node)
- */
-static slang_ir_node *
-_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
-{
- switch (oper->type) {
- case SLANG_OPER_BLOCK_NEW_SCOPE:
- {
- slang_ir_node *n;
-
- _slang_push_var_table(A->vartable);
-
- oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; /* temp change */
- n = _slang_gen_operation(A, oper);
- oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; /* restore */
-
- _slang_pop_var_table(A->vartable);
-
- /*_slang_undeclare_vars(oper->locals);*/
- /*print_vars(oper->locals);*/
-
- if (n)
- n = new_node1(IR_SCOPE, n);
- return n;
- }
- break;
-
- case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
- /* list of operations */
- if (oper->num_children > 0)
- {
- slang_ir_node *n, *tree = NULL;
- GLuint i;
-
- for (i = 0; i < oper->num_children; i++) {
- n = _slang_gen_operation(A, &oper->children[i]);
- if (!n) {
- _slang_free_ir_tree(tree);
- return NULL; /* error must have occured */
- }
- tree = new_seq(tree, n);
- }
-
- return tree;
- }
- else {
- return new_node0(IR_NOP);
- }
-
- case SLANG_OPER_EXPRESSION:
- return _slang_gen_operation(A, &oper->children[0]);
-
- case SLANG_OPER_FOR:
- return _slang_gen_for(A, oper);
- case SLANG_OPER_DO:
- return _slang_gen_do(A, oper);
- case SLANG_OPER_WHILE:
- return _slang_gen_while(A, oper);
- case SLANG_OPER_BREAK:
- if (!current_loop_oper(A)) {
- slang_info_log_error(A->log, "'break' not in loop");
- return NULL;
- }
- return new_break(current_loop_ir(A));
- case SLANG_OPER_CONTINUE:
- if (!current_loop_oper(A)) {
- slang_info_log_error(A->log, "'continue' not in loop");
- return NULL;
- }
- return _slang_gen_continue(A, oper);
- case SLANG_OPER_DISCARD:
- return new_node0(IR_KILL);
-
- case SLANG_OPER_EQUAL:
- return _slang_gen_compare(A, oper, IR_EQUAL);
- case SLANG_OPER_NOTEQUAL:
- return _slang_gen_compare(A, oper, IR_NOTEQUAL);
- case SLANG_OPER_GREATER:
- return _slang_gen_compare(A, oper, IR_SGT);
- case SLANG_OPER_LESS:
- return _slang_gen_compare(A, oper, IR_SLT);
- case SLANG_OPER_GREATEREQUAL:
- return _slang_gen_compare(A, oper, IR_SGE);
- case SLANG_OPER_LESSEQUAL:
- return _slang_gen_compare(A, oper, IR_SLE);
- case SLANG_OPER_ADD:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "+", oper, NULL);
- return n;
- }
- case SLANG_OPER_SUBTRACT:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "-", oper, NULL);
- return n;
- }
- case SLANG_OPER_MULTIPLY:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "*", oper, NULL);
- return n;
- }
- case SLANG_OPER_DIVIDE:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "/", oper, NULL);
- return n;
- }
- case SLANG_OPER_MINUS:
- {
- slang_ir_node *n;
- assert(oper->num_children == 1);
- n = _slang_gen_function_call_name(A, "-", oper, NULL);
- return n;
- }
- case SLANG_OPER_PLUS:
- /* +expr --> do nothing */
- return _slang_gen_operation(A, &oper->children[0]);
- case SLANG_OPER_VARIABLE_DECL:
- return _slang_gen_declaration(A, oper);
- case SLANG_OPER_ASSIGN:
- return _slang_gen_assignment(A, oper);
- case SLANG_OPER_ADDASSIGN:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "+=", oper, NULL);
- return n;
- }
- case SLANG_OPER_SUBASSIGN:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "-=", oper, NULL);
- return n;
- }
- break;
- case SLANG_OPER_MULASSIGN:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "*=", oper, NULL);
- return n;
- }
- case SLANG_OPER_DIVASSIGN:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_function_call_name(A, "/=", oper, NULL);
- return n;
- }
- case SLANG_OPER_LOGICALAND:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_logical_and(A, oper);
- return n;
- }
- case SLANG_OPER_LOGICALOR:
- {
- slang_ir_node *n;
- assert(oper->num_children == 2);
- n = _slang_gen_logical_or(A, oper);
- return n;
- }
- case SLANG_OPER_LOGICALXOR:
- return _slang_gen_xor(A, oper);
- case SLANG_OPER_NOT:
- return _slang_gen_not(A, oper);
- case SLANG_OPER_SELECT: /* b ? x : y */
- {
- slang_ir_node *n;
- assert(oper->num_children == 3);
- n = _slang_gen_select(A, oper);
- return n;
- }
-
- case SLANG_OPER_ASM:
- return _slang_gen_asm(A, oper, NULL);
- case SLANG_OPER_CALL:
- return _slang_gen_function_call_name(A, (const char *) oper->a_id,
- oper, NULL);
- case SLANG_OPER_METHOD:
- return _slang_gen_method_call(A, oper);
- case SLANG_OPER_RETURN:
- return _slang_gen_return(A, oper);
- case SLANG_OPER_RETURN_INLINED:
- return _slang_gen_return(A, oper);
- case SLANG_OPER_LABEL:
- return new_label(oper->label);
- case SLANG_OPER_IDENTIFIER:
- return _slang_gen_variable(A, oper);
- case SLANG_OPER_IF:
- return _slang_gen_if(A, oper);
- case SLANG_OPER_FIELD:
- return _slang_gen_struct_field(A, oper);
- case SLANG_OPER_SUBSCRIPT:
- return _slang_gen_array_element(A, oper);
- case SLANG_OPER_LITERAL_FLOAT:
- /* fall-through */
- case SLANG_OPER_LITERAL_INT:
- /* fall-through */
- case SLANG_OPER_LITERAL_BOOL:
- return new_float_literal(oper->literal, oper->literal_size);
-
- case SLANG_OPER_POSTINCREMENT: /* var++ */
- {
- slang_ir_node *n;
- assert(oper->num_children == 1);
- n = _slang_gen_function_call_name(A, "__postIncr", oper, NULL);
- return n;
- }
- case SLANG_OPER_POSTDECREMENT: /* var-- */
- {
- slang_ir_node *n;
- assert(oper->num_children == 1);
- n = _slang_gen_function_call_name(A, "__postDecr", oper, NULL);
- return n;
- }
- case SLANG_OPER_PREINCREMENT: /* ++var */
- {
- slang_ir_node *n;
- assert(oper->num_children == 1);
- n = _slang_gen_function_call_name(A, "++", oper, NULL);
- return n;
- }
- case SLANG_OPER_PREDECREMENT: /* --var */
- {
- slang_ir_node *n;
- assert(oper->num_children == 1);
- n = _slang_gen_function_call_name(A, "--", oper, NULL);
- return n;
- }
-
- case SLANG_OPER_NON_INLINED_CALL:
- case SLANG_OPER_SEQUENCE:
- {
- slang_ir_node *tree = NULL;
- GLuint i;
- for (i = 0; i < oper->num_children; i++) {
- slang_ir_node *n = _slang_gen_operation(A, &oper->children[i]);
- tree = new_seq(tree, n);
- if (n)
- tree->Store = n->Store;
- }
- if (oper->type == SLANG_OPER_NON_INLINED_CALL) {
- tree = new_function_call(tree, oper->label);
- }
- return tree;
- }
-
- case SLANG_OPER_NONE:
- case SLANG_OPER_VOID:
- /* returning NULL here would generate an error */
- return new_node0(IR_NOP);
-
- default:
- _mesa_problem(NULL, "bad node type %d in _slang_gen_operation",
- oper->type);
- return new_node0(IR_NOP);
- }
-
- return NULL;
-}
-
-
-/**
- * Check if the given type specifier is a rectangular texture sampler.
- */
-static GLboolean
-is_rect_sampler_spec(const slang_type_specifier *spec)
-{
- while (spec->_array) {
- spec = spec->_array;
- }
- return spec->type == SLANG_SPEC_SAMPLER_RECT ||
- spec->type == SLANG_SPEC_SAMPLER_RECT_SHADOW;
-}
-
-
-
-/**
- * Called by compiler when a global variable has been parsed/compiled.
- * Here we examine the variable's type to determine what kind of register
- * storage will be used.
- *
- * A uniform such as "gl_Position" will become the register specification
- * (PROGRAM_OUTPUT, VERT_RESULT_HPOS). Or, uniform "gl_FogFragCoord"
- * will be (PROGRAM_INPUT, FRAG_ATTRIB_FOGC).
- *
- * Samplers are interesting. For "uniform sampler2D tex;" we'll specify
- * (PROGRAM_SAMPLER, index) where index is resolved at link-time to an
- * actual texture unit (as specified by the user calling glUniform1i()).
- */
-GLboolean
-_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
- slang_unit_type type)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_program *prog = A->program;
- const char *varName = (char *) var->a_name;
- GLboolean success = GL_TRUE;
- slang_ir_storage *store = NULL;
- int dbg = 0;
- const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
- const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
- const GLint arrayLen = _slang_array_length(var);
- const GLint totalSize = _slang_array_size(size, arrayLen);
- GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
-
- var->is_global = GL_TRUE;
-
- /* check for sampler2D arrays */
- if (texIndex == -1 && var->type.specifier._array)
- texIndex = sampler_to_texture_index(var->type.specifier._array->type);
-
- if (texIndex != -1) {
- /* This is a texture sampler variable...
- * store->File = PROGRAM_SAMPLER
- * store->Index = sampler number (0..7, typically)
- * store->Size = texture type index (1D, 2D, 3D, cube, etc)
- */
- if (var->initializer) {
- slang_info_log_error(A->log, "illegal assignment to '%s'", varName);
- return GL_FALSE;
- }
-#if FEATURE_es2_glsl /* XXX should use FEATURE_texture_rect */
- /* disallow rect samplers */
- if (ctx->API == API_OPENGLES2 &&
- is_rect_sampler_spec(&var->type.specifier)) {
- slang_info_log_error(A->log, "invalid sampler type for '%s'", varName);
- return GL_FALSE;
- }
-#else
- (void) is_rect_sampler_spec; /* silence warning */
- (void) ctx;
-#endif
- {
- GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
- store = _slang_new_ir_storage_sampler(sampNum, texIndex, totalSize);
-
- /* If we have a sampler array, then we need to allocate the
- * additional samplers to ensure we don't allocate them elsewhere.
- * We can't directly use _mesa_add_sampler() as that checks the
- * varName and gets a match, so we call _mesa_add_parameter()
- * directly and use the last sampler number from the call above.
- */
- if (arrayLen > 0) {
- GLint a = arrayLen - 1;
- GLint i;
- for (i = 0; i < a; i++) {
- GLfloat value = (GLfloat)(i + sampNum + 1);
- (void) _mesa_add_parameter(prog->Parameters, PROGRAM_SAMPLER,
- varName, 1, datatype, &value, NULL, 0x0);
- }
- }
- }
- if (dbg) printf("SAMPLER ");
- }
- else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
- /* Uniform variable */
- const GLuint swizzle = _slang_var_swizzle(totalSize, 0);
-
- if (prog) {
- /* user-defined uniform */
- if (datatype == GL_NONE) {
- if ((var->type.specifier.type == SLANG_SPEC_ARRAY &&
- var->type.specifier._array->type == SLANG_SPEC_STRUCT) ||
- (var->type.specifier.type == SLANG_SPEC_STRUCT)) {
- /* temporary work-around */
- GLenum datatype = GL_FLOAT;
- GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName,
- totalSize, datatype, NULL);
- store = _slang_new_ir_storage_swz(PROGRAM_UNIFORM, uniformLoc,
- totalSize, swizzle);
-
- if (arrayLen > 0) {
- GLint a = arrayLen - 1;
- GLint i;
- for (i = 0; i < a; i++) {
- GLfloat value = (GLfloat)(i + uniformLoc + 1);
- (void) _mesa_add_parameter(prog->Parameters, PROGRAM_UNIFORM,
- varName, 1, datatype, &value, NULL, 0x0);
- }
- }
-
- /* XXX what we need to do is unroll the struct into its
- * basic types, creating a uniform variable for each.
- * For example:
- * struct foo {
- * vec3 a;
- * vec4 b;
- * };
- * uniform foo f;
- *
- * Should produce uniforms:
- * "f.a" (GL_FLOAT_VEC3)
- * "f.b" (GL_FLOAT_VEC4)
- */
-
- if (var->initializer) {
- slang_info_log_error(A->log,
- "unsupported initializer for uniform '%s'", varName);
- return GL_FALSE;
- }
- }
- else {
- slang_info_log_error(A->log,
- "invalid datatype for uniform variable %s",
- varName);
- return GL_FALSE;
- }
- }
- else {
- /* non-struct uniform */
- if (!_slang_gen_var_decl(A, var, var->initializer))
- return GL_FALSE;
- store = var->store;
- }
- }
- else {
- /* pre-defined uniform, like gl_ModelviewMatrix */
- /* We know it's a uniform, but don't allocate storage unless
- * it's really used.
- */
- store = _slang_new_ir_storage_swz(PROGRAM_STATE_VAR, -1,
- totalSize, swizzle);
- }
- if (dbg) printf("UNIFORM (sz %d) ", totalSize);
- }
- else if (var->type.qualifier == SLANG_QUAL_VARYING) {
- /* varyings must be float, vec or mat */
- if (!_slang_type_is_float_vec_mat(var->type.specifier.type) &&
- var->type.specifier.type != SLANG_SPEC_ARRAY) {
- slang_info_log_error(A->log,
- "varying '%s' must be float/vector/matrix",
- varName);
- return GL_FALSE;
- }
-
- if (var->initializer) {
- slang_info_log_error(A->log, "illegal initializer for varying '%s'",
- varName);
- return GL_FALSE;
- }
-
- if (prog) {
- /* user-defined varying */
- GLbitfield flags;
- GLint varyingLoc;
- GLuint swizzle;
-
- flags = 0x0;
- if (var->type.centroid == SLANG_CENTROID)
- flags |= PROG_PARAM_BIT_CENTROID;
- if (var->type.variant == SLANG_INVARIANT)
- flags |= PROG_PARAM_BIT_INVARIANT;
-
- varyingLoc = _mesa_add_varying(prog->Varying, varName,
- totalSize, GL_NONE, flags);
- swizzle = _slang_var_swizzle(size, 0);
- store = _slang_new_ir_storage_swz(PROGRAM_VARYING, varyingLoc,
- totalSize, swizzle);
- }
- else {
- /* pre-defined varying, like gl_Color or gl_TexCoord */
- if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
- /* fragment program input */
- GLuint swizzle;
- GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
- &swizzle, NULL);
- assert(index >= 0);
- assert(index < FRAG_ATTRIB_MAX);
- store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index,
- size, swizzle);
- } else if (type == SLANG_UNIT_VERTEX_BUILTIN) {
- /* vertex program output */
- GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
- GLuint swizzle = _slang_var_swizzle(size, 0);
- assert(index >= 0);
- assert(index < VERT_RESULT_MAX);
- assert(type == SLANG_UNIT_VERTEX_BUILTIN);
- store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index,
- size, swizzle);
- } else {
- /* geometry program input */
- GLboolean is_array = GL_FALSE;
- GLuint swizzle;
- GLint index = _slang_input_index(varName, MESA_GEOMETRY_PROGRAM,
- &swizzle, &is_array);
- if (index < 0) {
- /* geometry program output */
- index = _slang_output_index(varName, MESA_GEOMETRY_PROGRAM);
- swizzle = _slang_var_swizzle(size, 0);
-
- assert(index >= 0);
- assert(index < GEOM_RESULT_MAX);
-
- store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index,
- size, swizzle);
- } else {
- assert(index >= 0);
- /* assert(index < GEOM_ATTRIB_MAX); */
- if (is_array)
- store = _slang_new_ir_storage_2d(PROGRAM_INPUT, 0, index,
- size, swizzle);
- else
- store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index,
- size, swizzle);
- }
- }
- if (dbg) printf("V/F ");
- }
- if (dbg) printf("VARYING ");
- }
- else if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE) {
- GLuint swizzle;
- GLint index;
- /* attributes must be float, vec or mat */
- if (!_slang_type_is_float_vec_mat(var->type.specifier.type)) {
- slang_info_log_error(A->log,
- "attribute '%s' must be float/vector/matrix",
- varName);
- return GL_FALSE;
- }
-
- if (prog) {
- /* user-defined vertex attribute */
- const GLint attr = -1; /* unknown */
- swizzle = _slang_var_swizzle(size, 0);
- index = _mesa_add_attribute(prog->Attributes, varName,
- size, datatype, attr);
- assert(index >= 0);
- index = VERT_ATTRIB_GENERIC0 + index;
- }
- else {
- /* pre-defined vertex attrib */
- index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB, &swizzle, NULL);
- assert(index >= 0);
- }
- store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
- if (dbg) printf("ATTRIB ");
- }
- else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) {
- GLuint swizzle = SWIZZLE_XYZW; /* silence compiler warning */
- if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
- GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
- &swizzle, NULL);
- store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
- } else if (type == SLANG_UNIT_GEOMETRY_BUILTIN) {
- GLboolean is_array;
- GLint index = _slang_input_index(varName, MESA_GEOMETRY_PROGRAM,
- &swizzle, &is_array);
- if (is_array)
- store = _slang_new_ir_storage_2d(PROGRAM_INPUT, 0, index, size, swizzle);
- else
- store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
- }
- if (dbg) printf("INPUT ");
- }
- else if (var->type.qualifier == SLANG_QUAL_FIXEDOUTPUT) {
- if (type == SLANG_UNIT_VERTEX_BUILTIN) {
- GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
- store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
- } else if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
- GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB);
- GLint specialSize = 4; /* treat all fragment outputs as float[4] */
- assert(type == SLANG_UNIT_FRAGMENT_BUILTIN);
- store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize);
- } else {
- GLint index = _slang_output_index(varName, MESA_GEOMETRY_PROGRAM);
- GLint specialSize = 4; /* treat all fragment outputs as float[4] */
- assert(type == SLANG_UNIT_GEOMETRY_BUILTIN);
- store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize);
- }
- if (dbg) printf("OUTPUT ");
- }
- else if (var->type.qualifier == SLANG_QUAL_CONST && !prog) {
- /* pre-defined global constant, like gl_MaxLights */
- store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
- if (dbg) printf("CONST ");
- }
- else {
- /* ordinary variable (may be const) */
- slang_ir_node *n;
-
- /* IR node to declare the variable */
- n = _slang_gen_var_decl(A, var, var->initializer);
-
- /* emit GPU instructions */
- success = _slang_emit_code(n, A->vartable, A->program, A->pragmas, GL_FALSE, A->log);
-
- _slang_free_ir_tree(n);
- }
-
- if (dbg) printf("GLOBAL VAR %s idx %d\n", (char*) var->a_name,
- store ? store->Index : -2);
-
- if (store)
- var->store = store; /* save var's storage info */
-
- var->declared = GL_TRUE;
-
- return success;
-}
-
-
-/**
- * Produce an IR tree from a function AST (fun->body).
- * Then call the code emitter to convert the IR tree into gl_program
- * instructions.
- */
-GLboolean
-_slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
-{
- slang_ir_node *n;
- GLboolean success = GL_TRUE;
-
- if (strcmp((char *) fun->header.a_name, "main") != 0) {
- /* we only really generate code for main, all other functions get
- * inlined or codegen'd upon an actual call.
- */
-#if 0
- /* do some basic error checking though */
- if (fun->header.type.specifier.type != SLANG_SPEC_VOID) {
- /* check that non-void functions actually return something */
- slang_operation *op
- = _slang_find_node_type(fun->body, SLANG_OPER_RETURN);
- if (!op) {
- slang_info_log_error(A->log,
- "function \"%s\" has no return statement",
- (char *) fun->header.a_name);
- printf(
- "function \"%s\" has no return statement\n",
- (char *) fun->header.a_name);
- return GL_FALSE;
- }
- }
-#endif
- return GL_TRUE; /* not an error */
- }
-
-#if 0
- printf("\n*********** codegen_function %s\n", (char *) fun->header.a_name);
- slang_print_function(fun, 1);
-#endif
-
- /* should have been allocated earlier: */
- assert(A->program->Parameters );
- assert(A->program->Varying);
- assert(A->vartable);
-
- A->LoopDepth = 0;
- A->UseReturnFlag = GL_FALSE;
- A->CurFunction = fun;
-
- /* fold constant expressions, etc. */
- _slang_simplify(fun->body, &A->space, A->atoms);
-
-#if 0
- printf("\n*********** simplified %s\n", (char *) fun->header.a_name);
- slang_print_function(fun, 1);
-#endif
-
- /* Create an end-of-function label */
- A->curFuncEndLabel = _slang_label_new("__endOfFunc__main");
-
- /* push new vartable scope */
- _slang_push_var_table(A->vartable);
-
- /* Generate IR tree for the function body code */
- n = _slang_gen_operation(A, fun->body);
- if (n)
- n = new_node1(IR_SCOPE, n);
-
- /* pop vartable, restore previous */
- _slang_pop_var_table(A->vartable);
-
- if (!n) {
- /* XXX record error */
- return GL_FALSE;
- }
-
- /* append an end-of-function-label to IR tree */
- n = new_seq(n, new_label(A->curFuncEndLabel));
-
- /*_slang_label_delete(A->curFuncEndLabel);*/
- A->curFuncEndLabel = NULL;
-
-#if 0
- printf("************* New AST for %s *****\n", (char*)fun->header.a_name);
- slang_print_function(fun, 1);
-#endif
-#if 0
- printf("************* IR for %s *******\n", (char*)fun->header.a_name);
- _slang_print_ir_tree(n, 0);
-#endif
-#if 0
- printf("************* End codegen function ************\n\n");
-#endif
-
- if (A->UnresolvedRefs) {
- /* Can't codegen at this time.
- * At link time we'll concatenate all the vertex shaders and/or all
- * the fragment shaders and try recompiling.
- */
- return GL_TRUE;
- }
-
- /* Emit program instructions */
- success = _slang_emit_code(n, A->vartable, A->program, A->pragmas, GL_TRUE, A->log);
- _slang_free_ir_tree(n);
-
- /* free codegen context */
- /*
- free(A->codegen);
- */
-
- return success;
-}
-
diff --git a/src/mesa/slang/slang_codegen.h b/src/mesa/slang/slang_codegen.h
deleted file mode 100644
index ff0279bbfed..00000000000
--- a/src/mesa/slang/slang_codegen.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-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 SLANG_CODEGEN_H
-#define SLANG_CODEGEN_H
-
-
-#include "main/glheader.h"
-#include "slang_compile.h"
-#include "slang_compile_variable.h"
-#include "slang_typeinfo.h"
-#include "slang_utility.h"
-
-struct slang_function_;
-
-#define MAX_LOOP_DEPTH 30
-
-
-typedef struct slang_assemble_ctx_
-{
- slang_atom_pool *atoms;
- slang_name_space space;
- struct gl_program *program;
- struct gl_sl_pragmas *pragmas;
- slang_var_table *vartable;
- slang_info_log *log;
- GLboolean allow_uniform_initializers;
-
- /* current loop stack */
- const slang_operation *LoopOperStack[MAX_LOOP_DEPTH];
- struct slang_ir_node_ *LoopIRStack[MAX_LOOP_DEPTH];
- GLuint LoopDepth;
-
- /* current function */
- struct slang_function_ *CurFunction;
- struct slang_label_ *curFuncEndLabel;
- GLboolean UseReturnFlag;
-
- GLboolean UnresolvedRefs;
- GLboolean EmitContReturn;
-} slang_assemble_ctx;
-
-
-extern GLuint
-_slang_sizeof_type_specifier(const slang_type_specifier *spec);
-
-extern GLboolean
-_slang_codegen_function(slang_assemble_ctx *A , struct slang_function_ *fun);
-
-extern GLboolean
-_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
- slang_unit_type type);
-
-
-#endif /* SLANG_CODEGEN_H */
diff --git a/src/mesa/slang/slang_compile.c b/src/mesa/slang/slang_compile.c
deleted file mode 100644
index de1bb56cd9a..00000000000
--- a/src/mesa/slang/slang_compile.c
+++ /dev/null
@@ -1,3103 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
- * Copyright (C) 2008 VMware, 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.
- */
-
-/**
- * \file slang_compile.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "program/program.h"
-#include "program/programopt.h"
-#include "program/prog_optimize.h"
-#include "program/prog_print.h"
-#include "program/prog_parameter.h"
-#include "../../glsl/pp/sl_pp_public.h"
-#include "../../glsl/pp/sl_pp_purify.h"
-#include "../../glsl/cl/sl_cl_parse.h"
-#include "slang_codegen.h"
-#include "slang_compile.h"
-#include "slang_storage.h"
-#include "slang_log.h"
-#include "slang_mem.h"
-#include "slang_vartable.h"
-#include "slang_simplify.h"
-
-/*
- * This is a straightforward implementation of the slang front-end
- * compiler. Lots of error-checking functionality is missing but
- * every well-formed shader source should compile successfully and
- * execute as expected. However, some semantically ill-formed shaders
- * may be accepted resulting in undefined behaviour.
- */
-
-
-/** re-defined below, should be the same though */
-#define TYPE_SPECIFIER_COUNT 36
-
-
-/**
- * Check if the given identifier is legal.
- */
-static GLboolean
-legal_identifier(slang_atom name)
-{
- /* "gl_" is a reserved prefix */
- if (strncmp((char *) name, "gl_", 3) == 0) {
- return GL_FALSE;
- }
- return GL_TRUE;
-}
-
-
-/*
- * slang_code_unit
- */
-
-GLvoid
-_slang_code_unit_ctr(slang_code_unit * self,
- struct slang_code_object_ * object)
-{
- _slang_variable_scope_ctr(&self->vars);
- _slang_function_scope_ctr(&self->funs);
- _slang_struct_scope_ctr(&self->structs);
- self->object = object;
-}
-
-GLvoid
-_slang_code_unit_dtr(slang_code_unit * self)
-{
- slang_variable_scope_destruct(&self->vars);
- slang_function_scope_destruct(&self->funs);
- slang_struct_scope_destruct(&self->structs);
-}
-
-/*
- * slang_code_object
- */
-
-GLvoid
-_slang_code_object_ctr(slang_code_object * self)
-{
- GLuint i;
-
- for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
- _slang_code_unit_ctr(&self->builtin[i], self);
- _slang_code_unit_ctr(&self->unit, self);
- slang_atom_pool_construct(&self->atompool);
-}
-
-GLvoid
-_slang_code_object_dtr(slang_code_object * self)
-{
- GLuint i;
-
- for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
- _slang_code_unit_dtr(&self->builtin[i]);
- _slang_code_unit_dtr(&self->unit);
- slang_atom_pool_destruct(&self->atompool);
-}
-
-
-/* slang_parse_ctx */
-
-typedef struct slang_parse_ctx_
-{
- const unsigned char *I;
- slang_info_log *L;
- int parsing_builtin;
- GLboolean global_scope; /**< Is object being declared a global? */
- slang_atom_pool *atoms;
- slang_unit_type type; /**< Vertex vs. Fragment */
- GLuint version; /**< user-specified (or default) #version */
-} slang_parse_ctx;
-
-/* slang_output_ctx */
-
-typedef struct slang_output_ctx_
-{
- slang_variable_scope *vars;
- slang_function_scope *funs;
- slang_struct_scope *structs;
- struct gl_program *program;
- struct gl_sl_pragmas *pragmas;
- slang_var_table *vartable;
- GLuint default_precision[TYPE_SPECIFIER_COUNT];
- GLboolean allow_precision;
- GLboolean allow_invariant;
- GLboolean allow_centroid;
- GLboolean allow_array_types; /* float[] syntax */
-} slang_output_ctx;
-
-/* _slang_compile() */
-
-
-/* Debugging aid, print file/line where parsing error is detected */
-#define RETURN0 \
- do { \
- if (0) \
- printf("slang error at %s:%d\n", __FILE__, __LINE__); \
- return 0; \
- } while (0)
-
-
-static void
-parse_identifier_str(slang_parse_ctx * C, char **id)
-{
- *id = (char *) C->I;
- C->I += strlen(*id) + 1;
-}
-
-static slang_atom
-parse_identifier(slang_parse_ctx * C)
-{
- const char *id;
-
- id = (const char *) C->I;
- C->I += strlen(id) + 1;
- return slang_atom_pool_atom(C->atoms, id);
-}
-
-static int
-is_hex_digit(char c)
-{
- return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
-}
-
-static int
-parse_general_number(slang_parse_ctx *ctx, float *number)
-{
- char *flt = NULL;
-
- if (*ctx->I == '0') {
- int value = 0;
- const unsigned char *pi;
-
- if (ctx->I[1] == 'x' || ctx->I[1] == 'X') {
- ctx->I += 2;
- if (!is_hex_digit(*ctx->I)) {
- return 0;
- }
- do {
- int digit;
-
- if (*ctx->I >= '0' && *ctx->I <= '9') {
- digit = (int)(*ctx->I - '0');
- } else if (*ctx->I >= 'a' && *ctx->I <= 'f') {
- digit = (int)(*ctx->I - 'a') + 10;
- } else {
- digit = (int)(*ctx->I - 'A') + 10;
- }
- value = value * 0x10 + digit;
- ctx->I++;
- } while (is_hex_digit(*ctx->I));
- if (*ctx->I != '\0') {
- return 0;
- }
- ctx->I++;
- *number = (float)value;
- return 1;
- }
-
- pi = ctx->I;
- pi++;
- while (*pi >= '0' && *pi <= '7') {
- int digit;
-
- digit = (int)(*pi - '0');
- value = value * 010 + digit;
- pi++;
- }
- if (*pi == '\0') {
- pi++;
- ctx->I = pi;
- *number = (float)value;
- return 1;
- }
- }
-
- parse_identifier_str(ctx, &flt);
- flt = _mesa_strdup(flt);
- if (!flt) {
- return 0;
- }
- if (flt[strlen(flt) - 1] == 'f' || flt[strlen(flt) - 1] == 'F') {
- flt[strlen(flt) - 1] = '\0';
- }
- *number = _mesa_strtof(flt, (char **)NULL);
- free(flt);
-
- return 1;
-}
-
-static int
-parse_number(slang_parse_ctx * C, int *number)
-{
- const int radix = (int) (*C->I++);
-
- if (radix == 1) {
- float f = 0.0f;
-
- parse_general_number(C, &f);
- *number = (int)f;
- } else {
- *number = 0;
- while (*C->I != '\0') {
- int digit;
- if (*C->I >= '0' && *C->I <= '9')
- digit = (int) (*C->I - '0');
- else if (*C->I >= 'A' && *C->I <= 'Z')
- digit = (int) (*C->I - 'A') + 10;
- else
- digit = (int) (*C->I - 'a') + 10;
- *number = *number * radix + digit;
- C->I++;
- }
- C->I++;
- }
- if (*number > 65535)
- slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);
- return 1;
-}
-
-static int
-parse_float(slang_parse_ctx * C, float *number)
-{
- if (*C->I == 1) {
- C->I++;
- parse_general_number(C, number);
- } else {
- char *integral = NULL;
- char *fractional = NULL;
- char *exponent = NULL;
- char *whole = NULL;
-
- parse_identifier_str(C, &integral);
- parse_identifier_str(C, &fractional);
- parse_identifier_str(C, &exponent);
-
- whole = (char *) _slang_alloc((strlen(integral) +
- strlen(fractional) +
- strlen(exponent) + 3) * sizeof(char));
- if (whole == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
-
- slang_string_copy(whole, integral);
- slang_string_concat(whole, ".");
- slang_string_concat(whole, fractional);
- slang_string_concat(whole, "E");
- slang_string_concat(whole, exponent);
-
- *number = _mesa_strtof(whole, (char **) NULL);
-
- _slang_free(whole);
- }
-
- return 1;
-}
-
-/* revision number - increment after each change affecting emitted output */
-#define REVISION 5
-
-static int
-check_revision(slang_parse_ctx * C)
-{
- if (*C->I != REVISION) {
- slang_info_log_error(C->L, "Internal compiler error.");
- RETURN0;
- }
- C->I++;
- return 1;
-}
-
-static int parse_statement(slang_parse_ctx *, slang_output_ctx *,
- slang_operation *);
-static int parse_expression(slang_parse_ctx *, slang_output_ctx *,
- slang_operation *);
-static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *,
- slang_type_specifier *);
-static int
-parse_type_array_size(slang_parse_ctx *C,
- slang_output_ctx *O,
- GLint *array_len);
-
-static GLboolean
-parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len)
-{
- slang_operation array_size;
- slang_name_space space;
- GLboolean result;
-
- if (!slang_operation_construct(&array_size))
- return GL_FALSE;
- if (!parse_expression(C, O, &array_size)) {
- slang_operation_destruct(&array_size);
- return GL_FALSE;
- }
-
- space.funcs = O->funs;
- space.structs = O->structs;
- space.vars = O->vars;
-
- /* evaluate compile-time expression which is array size */
- _slang_simplify(&array_size, &space, C->atoms);
-
- if (array_size.type == SLANG_OPER_LITERAL_INT) {
- result = GL_TRUE;
- *len = (GLint) array_size.literal[0];
- } else if (array_size.type == SLANG_OPER_IDENTIFIER) {
- slang_variable *var = _slang_variable_locate(array_size.locals, array_size.a_id, GL_TRUE);
- if (!var) {
- slang_info_log_error(C->L, "undefined variable '%s'",
- (char *) array_size.a_id);
- result = GL_FALSE;
- } else if (var->type.qualifier == SLANG_QUAL_CONST &&
- var->type.specifier.type == SLANG_SPEC_INT) {
- if (var->initializer &&
- var->initializer->type == SLANG_OPER_LITERAL_INT) {
- *len = (GLint) var->initializer->literal[0];
- result = GL_TRUE;
- } else {
- slang_info_log_error(C->L, "unable to parse array size declaration");
- result = GL_FALSE;
- }
- } else {
- slang_info_log_error(C->L, "unable to parse array size declaration");
- result = GL_FALSE;
- }
- } else {
- result = GL_FALSE;
- }
-
- slang_operation_destruct(&array_size);
- return result;
-}
-
-static GLboolean
-calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O,
- slang_variable * var)
-{
- slang_storage_aggregate agg;
-
- if (!slang_storage_aggregate_construct(&agg))
- return GL_FALSE;
- if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len,
- O->funs, O->structs, O->vars, C->atoms)) {
- slang_storage_aggregate_destruct(&agg);
- return GL_FALSE;
- }
- var->size = _slang_sizeof_aggregate(&agg);
- slang_storage_aggregate_destruct(&agg);
- return GL_TRUE;
-}
-
-static void
-promote_type_to_array(slang_parse_ctx *C,
- slang_fully_specified_type *type,
- GLint array_len)
-{
- slang_type_specifier *baseType =
- slang_type_specifier_new(type->specifier.type, NULL, NULL);
-
- type->specifier.type = SLANG_SPEC_ARRAY;
- type->specifier._array = baseType;
- type->array_len = array_len;
-}
-
-
-static GLboolean
-convert_to_array(slang_parse_ctx * C, slang_variable * var,
- const slang_type_specifier * sp)
-{
- /* sized array - mark it as array, copy the specifier to the array element
- * and parse the expression */
- var->type.specifier.type = SLANG_SPEC_ARRAY;
- var->type.specifier._array = (slang_type_specifier *)
- _slang_alloc(sizeof(slang_type_specifier));
- if (var->type.specifier._array == NULL) {
- slang_info_log_memory(C->L);
- return GL_FALSE;
- }
- slang_type_specifier_ctr(var->type.specifier._array);
- return slang_type_specifier_copy(var->type.specifier._array, sp);
-}
-
-/* structure field */
-#define FIELD_NONE 0
-#define FIELD_NEXT 1
-#define FIELD_ARRAY 2
-
-static GLboolean
-parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O,
- slang_variable * var, slang_atom a_name,
- const slang_type_specifier * sp,
- GLuint array_len)
-{
- var->a_name = a_name;
- if (var->a_name == SLANG_ATOM_NULL)
- return GL_FALSE;
-
- switch (*C->I++) {
- case FIELD_NONE:
- if (array_len != -1) {
- if (!convert_to_array(C, var, sp))
- return GL_FALSE;
- var->array_len = array_len;
- }
- else {
- if (!slang_type_specifier_copy(&var->type.specifier, sp))
- return GL_FALSE;
- }
- break;
- case FIELD_ARRAY:
- if (array_len != -1)
- return GL_FALSE;
- if (!convert_to_array(C, var, sp))
- return GL_FALSE;
- if (!parse_array_len(C, O, &var->array_len))
- return GL_FALSE;
- break;
- default:
- return GL_FALSE;
- }
-
- return calculate_var_size(C, O, var);
-}
-
-static int
-parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,
- slang_struct * st, slang_type_specifier * sp)
-{
- slang_output_ctx o = *O;
- GLint array_len;
-
- o.structs = st->structs;
- if (!parse_type_specifier(C, &o, sp))
- RETURN0;
- if (!parse_type_array_size(C, &o, &array_len))
- RETURN0;
-
- do {
- slang_atom a_name;
- slang_variable *var = slang_variable_scope_grow(st->fields);
- if (!var) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- a_name = parse_identifier(C);
- if (_slang_variable_locate(st->fields, a_name, GL_FALSE)) {
- slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name);
- RETURN0;
- }
-
- if (!parse_struct_field_var(C, &o, var, a_name, sp, array_len))
- RETURN0;
- }
- while (*C->I++ != FIELD_NONE);
-
- return 1;
-}
-
-static int
-parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
-{
- slang_atom a_name;
- const char *name;
-
- /* parse struct name (if any) and make sure it is unique in current scope */
- a_name = parse_identifier(C);
- if (a_name == SLANG_ATOM_NULL)
- RETURN0;
-
- name = slang_atom_pool_id(C->atoms, a_name);
- if (name[0] != '\0'
- && slang_struct_scope_find(O->structs, a_name, 0) != NULL) {
- slang_info_log_error(C->L, "%s: duplicate type name.", name);
- RETURN0;
- }
-
- /* set-up a new struct */
- *st = (slang_struct *) _slang_alloc(sizeof(slang_struct));
- if (*st == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- if (!slang_struct_construct(*st)) {
- _slang_free(*st);
- *st = NULL;
- slang_info_log_memory(C->L);
- RETURN0;
- }
- (**st).a_name = a_name;
- (**st).structs->outer_scope = O->structs;
-
- /* parse individual struct fields */
- do {
- slang_type_specifier sp;
-
- slang_type_specifier_ctr(&sp);
- if (!parse_struct_field(C, O, *st, &sp)) {
- slang_type_specifier_dtr(&sp);
- RETURN0;
- }
- slang_type_specifier_dtr(&sp);
- }
- while (*C->I++ != FIELD_NONE);
-
- /* if named struct, copy it to current scope */
- if (name[0] != '\0') {
- slang_struct *s;
-
- O->structs->structs =
- (slang_struct *) _slang_realloc(O->structs->structs,
- O->structs->num_structs
- * sizeof(slang_struct),
- (O->structs->num_structs + 1)
- * sizeof(slang_struct));
- if (O->structs->structs == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- s = &O->structs->structs[O->structs->num_structs];
- if (!slang_struct_construct(s))
- RETURN0;
- O->structs->num_structs++;
- if (!slang_struct_copy(s, *st))
- RETURN0;
- }
-
- return 1;
-}
-
-
-/* invariant qualifer */
-#define TYPE_VARIANT 90
-#define TYPE_INVARIANT 91
-
-static int
-parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant)
-{
- GLuint invariant = *C->I++;
- switch (invariant) {
- case TYPE_VARIANT:
- *variant = SLANG_VARIANT;
- return 1;
- case TYPE_INVARIANT:
- *variant = SLANG_INVARIANT;
- return 1;
- default:
- RETURN0;
- }
-}
-
-
-/* centroid qualifer */
-#define TYPE_CENTER 95
-#define TYPE_CENTROID 96
-
-static int
-parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid)
-{
- GLuint c = *C->I++;
- switch (c) {
- case TYPE_CENTER:
- *centroid = SLANG_CENTER;
- return 1;
- case TYPE_CENTROID:
- *centroid = SLANG_CENTROID;
- return 1;
- default:
- RETURN0;
- }
-}
-
-
-/* Layout qualifiers */
-#define LAYOUT_QUALIFIER_NONE 0
-#define LAYOUT_QUALIFIER_UPPER_LEFT 1
-#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER 2
-
-static int
-parse_layout_qualifiers(slang_parse_ctx * C, slang_layout_qualifier *layout)
-{
- *layout = 0x0;
-
- /* the layout qualifiers come as a list of LAYOUT_QUALIFER_x tokens,
- * terminated by LAYOUT_QUALIFIER_NONE.
- */
- while (1) {
- GLuint c = *C->I++;
- switch (c) {
- case LAYOUT_QUALIFIER_NONE:
- /* end of list of qualifiers */
- return 1;
- case LAYOUT_QUALIFIER_UPPER_LEFT:
- *layout |= SLANG_LAYOUT_UPPER_LEFT_BIT;
- break;
- case LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER:
- *layout |= SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT;
- break;
- default:
- assert(0 && "Bad layout qualifier");
- }
- }
-}
-
-
-/* type qualifier */
-#define TYPE_QUALIFIER_NONE 0
-#define TYPE_QUALIFIER_CONST 1
-#define TYPE_QUALIFIER_ATTRIBUTE 2
-#define TYPE_QUALIFIER_VARYING 3
-#define TYPE_QUALIFIER_UNIFORM 4
-#define TYPE_QUALIFIER_FIXEDOUTPUT 5
-#define TYPE_QUALIFIER_FIXEDINPUT 6
-
-static int
-parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual)
-{
- GLuint qualifier = *C->I++;
- switch (qualifier) {
- case TYPE_QUALIFIER_NONE:
- *qual = SLANG_QUAL_NONE;
- break;
- case TYPE_QUALIFIER_CONST:
- *qual = SLANG_QUAL_CONST;
- break;
- case TYPE_QUALIFIER_ATTRIBUTE:
- *qual = SLANG_QUAL_ATTRIBUTE;
- break;
- case TYPE_QUALIFIER_VARYING:
- *qual = SLANG_QUAL_VARYING;
- break;
- case TYPE_QUALIFIER_UNIFORM:
- *qual = SLANG_QUAL_UNIFORM;
- break;
- case TYPE_QUALIFIER_FIXEDOUTPUT:
- *qual = SLANG_QUAL_FIXEDOUTPUT;
- break;
- case TYPE_QUALIFIER_FIXEDINPUT:
- *qual = SLANG_QUAL_FIXEDINPUT;
- break;
- default:
- RETURN0;
- }
- return 1;
-}
-
-/* type specifier */
-#define TYPE_SPECIFIER_VOID 0
-#define TYPE_SPECIFIER_BOOL 1
-#define TYPE_SPECIFIER_BVEC2 2
-#define TYPE_SPECIFIER_BVEC3 3
-#define TYPE_SPECIFIER_BVEC4 4
-#define TYPE_SPECIFIER_INT 5
-#define TYPE_SPECIFIER_IVEC2 6
-#define TYPE_SPECIFIER_IVEC3 7
-#define TYPE_SPECIFIER_IVEC4 8
-#define TYPE_SPECIFIER_FLOAT 9
-#define TYPE_SPECIFIER_VEC2 10
-#define TYPE_SPECIFIER_VEC3 11
-#define TYPE_SPECIFIER_VEC4 12
-#define TYPE_SPECIFIER_MAT2 13
-#define TYPE_SPECIFIER_MAT3 14
-#define TYPE_SPECIFIER_MAT4 15
-#define TYPE_SPECIFIER_SAMPLER1D 16
-#define TYPE_SPECIFIER_SAMPLER2D 17
-#define TYPE_SPECIFIER_SAMPLER3D 18
-#define TYPE_SPECIFIER_SAMPLERCUBE 19
-#define TYPE_SPECIFIER_SAMPLER1DSHADOW 20
-#define TYPE_SPECIFIER_SAMPLER2DSHADOW 21
-#define TYPE_SPECIFIER_SAMPLER2DRECT 22
-#define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23
-#define TYPE_SPECIFIER_STRUCT 24
-#define TYPE_SPECIFIER_TYPENAME 25
-#define TYPE_SPECIFIER_MAT23 26
-#define TYPE_SPECIFIER_MAT32 27
-#define TYPE_SPECIFIER_MAT24 28
-#define TYPE_SPECIFIER_MAT42 29
-#define TYPE_SPECIFIER_MAT34 30
-#define TYPE_SPECIFIER_MAT43 31
-#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY 32
-#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY 33
-#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW 34
-#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW 35
-#define TYPE_SPECIFIER_COUNT 36
-
-static int
-parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
- slang_type_specifier * spec)
-{
- int type = *C->I++;
- switch (type) {
- case TYPE_SPECIFIER_VOID:
- spec->type = SLANG_SPEC_VOID;
- break;
- case TYPE_SPECIFIER_BOOL:
- spec->type = SLANG_SPEC_BOOL;
- break;
- case TYPE_SPECIFIER_BVEC2:
- spec->type = SLANG_SPEC_BVEC2;
- break;
- case TYPE_SPECIFIER_BVEC3:
- spec->type = SLANG_SPEC_BVEC3;
- break;
- case TYPE_SPECIFIER_BVEC4:
- spec->type = SLANG_SPEC_BVEC4;
- break;
- case TYPE_SPECIFIER_INT:
- spec->type = SLANG_SPEC_INT;
- break;
- case TYPE_SPECIFIER_IVEC2:
- spec->type = SLANG_SPEC_IVEC2;
- break;
- case TYPE_SPECIFIER_IVEC3:
- spec->type = SLANG_SPEC_IVEC3;
- break;
- case TYPE_SPECIFIER_IVEC4:
- spec->type = SLANG_SPEC_IVEC4;
- break;
- case TYPE_SPECIFIER_FLOAT:
- spec->type = SLANG_SPEC_FLOAT;
- break;
- case TYPE_SPECIFIER_VEC2:
- spec->type = SLANG_SPEC_VEC2;
- break;
- case TYPE_SPECIFIER_VEC3:
- spec->type = SLANG_SPEC_VEC3;
- break;
- case TYPE_SPECIFIER_VEC4:
- spec->type = SLANG_SPEC_VEC4;
- break;
- case TYPE_SPECIFIER_MAT2:
- spec->type = SLANG_SPEC_MAT2;
- break;
- case TYPE_SPECIFIER_MAT3:
- spec->type = SLANG_SPEC_MAT3;
- break;
- case TYPE_SPECIFIER_MAT4:
- spec->type = SLANG_SPEC_MAT4;
- break;
- case TYPE_SPECIFIER_MAT23:
- spec->type = SLANG_SPEC_MAT23;
- break;
- case TYPE_SPECIFIER_MAT32:
- spec->type = SLANG_SPEC_MAT32;
- break;
- case TYPE_SPECIFIER_MAT24:
- spec->type = SLANG_SPEC_MAT24;
- break;
- case TYPE_SPECIFIER_MAT42:
- spec->type = SLANG_SPEC_MAT42;
- break;
- case TYPE_SPECIFIER_MAT34:
- spec->type = SLANG_SPEC_MAT34;
- break;
- case TYPE_SPECIFIER_MAT43:
- spec->type = SLANG_SPEC_MAT43;
- break;
- case TYPE_SPECIFIER_SAMPLER1D:
- spec->type = SLANG_SPEC_SAMPLER_1D;
- break;
- case TYPE_SPECIFIER_SAMPLER2D:
- spec->type = SLANG_SPEC_SAMPLER_2D;
- break;
- case TYPE_SPECIFIER_SAMPLER3D:
- spec->type = SLANG_SPEC_SAMPLER_3D;
- break;
- case TYPE_SPECIFIER_SAMPLERCUBE:
- spec->type = SLANG_SPEC_SAMPLER_CUBE;
- break;
- case TYPE_SPECIFIER_SAMPLER2DRECT:
- spec->type = SLANG_SPEC_SAMPLER_RECT;
- break;
- case TYPE_SPECIFIER_SAMPLER1DSHADOW:
- spec->type = SLANG_SPEC_SAMPLER_1D_SHADOW;
- break;
- case TYPE_SPECIFIER_SAMPLER2DSHADOW:
- spec->type = SLANG_SPEC_SAMPLER_2D_SHADOW;
- break;
- case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
- spec->type = SLANG_SPEC_SAMPLER_RECT_SHADOW;
- break;
- case TYPE_SPECIFIER_SAMPLER_1D_ARRAY:
- spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY;
- break;
- case TYPE_SPECIFIER_SAMPLER_2D_ARRAY:
- spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY;
- break;
- case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW:
- spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW;
- break;
- case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW:
- spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW;
- break;
- case TYPE_SPECIFIER_STRUCT:
- spec->type = SLANG_SPEC_STRUCT;
- if (!parse_struct(C, O, &spec->_struct))
- RETURN0;
- break;
- case TYPE_SPECIFIER_TYPENAME:
- spec->type = SLANG_SPEC_STRUCT;
- {
- slang_atom a_name;
- slang_struct *stru;
-
- a_name = parse_identifier(C);
- if (a_name == NULL)
- RETURN0;
-
- stru = slang_struct_scope_find(O->structs, a_name, 1);
- if (stru == NULL) {
- slang_info_log_error(C->L, "undeclared type name '%s'",
- slang_atom_pool_id(C->atoms, a_name));
- RETURN0;
- }
-
- spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
- if (spec->_struct == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- if (!slang_struct_construct(spec->_struct)) {
- _slang_free(spec->_struct);
- spec->_struct = NULL;
- RETURN0;
- }
- if (!slang_struct_copy(spec->_struct, stru))
- RETURN0;
- }
- break;
- default:
- RETURN0;
- }
- return 1;
-}
-
-#define TYPE_SPECIFIER_NONARRAY 0
-#define TYPE_SPECIFIER_ARRAY 1
-
-static int
-parse_type_array_size(slang_parse_ctx *C,
- slang_output_ctx *O,
- GLint *array_len)
-{
- GLuint size;
-
- switch (*C->I++) {
- case TYPE_SPECIFIER_NONARRAY:
- *array_len = -1; /* -1 = not an array */
- break;
- case TYPE_SPECIFIER_ARRAY:
- if (!parse_array_len(C, O, &size))
- RETURN0;
- *array_len = (GLint) size;
- break;
- default:
- assert(0);
- RETURN0;
- }
- return 1;
-}
-
-#define PRECISION_DEFAULT 0
-#define PRECISION_LOW 1
-#define PRECISION_MEDIUM 2
-#define PRECISION_HIGH 3
-
-static int
-parse_type_precision(slang_parse_ctx *C,
- slang_type_precision *precision)
-{
- GLint prec = *C->I++;
- switch (prec) {
- case PRECISION_DEFAULT:
- *precision = SLANG_PREC_DEFAULT;
- return 1;
- case PRECISION_LOW:
- *precision = SLANG_PREC_LOW;
- return 1;
- case PRECISION_MEDIUM:
- *precision = SLANG_PREC_MEDIUM;
- return 1;
- case PRECISION_HIGH:
- *precision = SLANG_PREC_HIGH;
- return 1;
- default:
- RETURN0;
- }
-}
-
-
-/* parameter qualifier */
-#define PARAM_QUALIFIER_IN 0
-#define PARAM_QUALIFIER_OUT 1
-#define PARAM_QUALIFIER_INOUT 2
-#define PARAM_QUALIFIER_NONE 3
-static int
-parse_varying_qualifier(slang_parse_ctx * C, slang_fully_specified_type *type)
-{
- int param_qual = *C->I++;
-
- if (type->qualifier != SLANG_QUAL_VARYING &&
- param_qual != PARAM_QUALIFIER_NONE) {
- slang_info_log_error(C->L, "Invalid type qualifier.");
- RETURN0;
- }
- switch (param_qual) {
- case PARAM_QUALIFIER_IN:
- case PARAM_QUALIFIER_NONE:
- type->varying_kind = SLANG_VARYING_IN;
- break;
- case PARAM_QUALIFIER_OUT:
- type->varying_kind = SLANG_VARYING_OUT;
- break;
- case PARAM_QUALIFIER_INOUT:
- slang_info_log_error(C->L, "Invalid type qualifier.");
- RETURN0;
- break;
- default:
- RETURN0;
- }
- return 1;
-}
-
-static int
-parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
- slang_fully_specified_type * type)
-{
- if (!parse_layout_qualifiers(C, &type->layout))
- RETURN0;
-
- if (!parse_type_variant(C, &type->variant))
- RETURN0;
-
- if (!parse_type_centroid(C, &type->centroid))
- RETURN0;
-
- if (!parse_type_qualifier(C, &type->qualifier))
- RETURN0;
-
- if (!parse_varying_qualifier(C, type))
- RETURN0;
-
- if (!parse_type_precision(C, &type->precision))
- RETURN0;
-
- if (!parse_type_specifier(C, O, &type->specifier))
- RETURN0;
-
- if (!parse_type_array_size(C, O, &type->array_len))
- RETURN0;
-
- if (!O->allow_invariant && type->variant == SLANG_INVARIANT) {
- slang_info_log_error(C->L,
- "'invariant' keyword not allowed (perhaps set #version 120)");
- RETURN0;
- }
-
- if (!O->allow_centroid && type->centroid == SLANG_CENTROID) {
- slang_info_log_error(C->L,
- "'centroid' keyword not allowed (perhaps set #version 120)");
- RETURN0;
- }
- else if (type->centroid == SLANG_CENTROID &&
- type->qualifier != SLANG_QUAL_VARYING) {
- slang_info_log_error(C->L,
- "'centroid' keyword only allowed for varying vars");
- RETURN0;
- }
-
-
- /* need this?
- if (type->qualifier != SLANG_QUAL_VARYING &&
- type->variant == SLANG_INVARIANT) {
- slang_info_log_error(C->L,
- "invariant qualifer only allowed for varying vars");
- RETURN0;
- }
- */
-
- if (O->allow_precision) {
- if (type->precision == SLANG_PREC_DEFAULT) {
- assert(type->specifier.type < TYPE_SPECIFIER_COUNT);
- /* use the default precision for this datatype */
- type->precision = O->default_precision[type->specifier.type];
- }
- }
- else {
- /* only default is allowed */
- if (type->precision != SLANG_PREC_DEFAULT) {
- slang_info_log_error(C->L, "precision qualifiers not allowed");
- RETURN0;
- }
- }
-
- if (!O->allow_array_types && type->array_len >= 0) {
- slang_info_log_error(C->L, "first-class array types not allowed");
- RETURN0;
- }
-
- if (type->array_len >= 0) {
- /* convert type to array type (ex: convert "int" to "array of int" */
- promote_type_to_array(C, type, type->array_len);
- }
-
- return 1;
-}
-
-/* operation */
-#define OP_END 0
-#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
-#define OP_BLOCK_BEGIN_NEW_SCOPE 2
-#define OP_DECLARE 3
-#define OP_ASM 4
-#define OP_BREAK 5
-#define OP_CONTINUE 6
-#define OP_DISCARD 7
-#define OP_RETURN 8
-#define OP_EXPRESSION 9
-#define OP_IF 10
-#define OP_WHILE 11
-#define OP_DO 12
-#define OP_FOR 13
-#define OP_PUSH_VOID 14
-#define OP_PUSH_BOOL 15
-#define OP_PUSH_INT 16
-#define OP_PUSH_FLOAT 17
-#define OP_PUSH_IDENTIFIER 18
-#define OP_SEQUENCE 19
-#define OP_ASSIGN 20
-#define OP_ADDASSIGN 21
-#define OP_SUBASSIGN 22
-#define OP_MULASSIGN 23
-#define OP_DIVASSIGN 24
-/*#define OP_MODASSIGN 25*/
-/*#define OP_LSHASSIGN 26*/
-/*#define OP_RSHASSIGN 27*/
-/*#define OP_ORASSIGN 28*/
-/*#define OP_XORASSIGN 29*/
-/*#define OP_ANDASSIGN 30*/
-#define OP_SELECT 31
-#define OP_LOGICALOR 32
-#define OP_LOGICALXOR 33
-#define OP_LOGICALAND 34
-/*#define OP_BITOR 35*/
-/*#define OP_BITXOR 36*/
-/*#define OP_BITAND 37*/
-#define OP_EQUAL 38
-#define OP_NOTEQUAL 39
-#define OP_LESS 40
-#define OP_GREATER 41
-#define OP_LESSEQUAL 42
-#define OP_GREATEREQUAL 43
-/*#define OP_LSHIFT 44*/
-/*#define OP_RSHIFT 45*/
-#define OP_ADD 46
-#define OP_SUBTRACT 47
-#define OP_MULTIPLY 48
-#define OP_DIVIDE 49
-/*#define OP_MODULUS 50*/
-#define OP_PREINCREMENT 51
-#define OP_PREDECREMENT 52
-#define OP_PLUS 53
-#define OP_MINUS 54
-/*#define OP_COMPLEMENT 55*/
-#define OP_NOT 56
-#define OP_SUBSCRIPT 57
-#define OP_CALL 58
-#define OP_FIELD 59
-#define OP_POSTINCREMENT 60
-#define OP_POSTDECREMENT 61
-#define OP_PRECISION 62
-#define OP_METHOD 63
-
-
-/**
- * When parsing a compound production, this function is used to parse the
- * children.
- * For example, a while-loop compound will have two children, the
- * while condition expression and the loop body. So, this function will
- * be called twice to parse those two sub-expressions.
- * \param C the parsing context
- * \param O the output context
- * \param oper the operation we're parsing
- * \param statement indicates whether parsing a statement, or expression
- * \return 1 if success, 0 if error
- */
-static int
-parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
- slang_operation * oper, GLboolean statement)
-{
- slang_operation *ch;
-
- /* grow child array */
- ch = slang_operation_grow(&oper->num_children, &oper->children);
- if (statement)
- return parse_statement(C, O, ch);
- return parse_expression(C, O, ch);
-}
-
-static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O);
-
-static int
-parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
- slang_operation * oper)
-{
- int op;
-
- oper->locals->outer_scope = O->vars;
-
- op = *C->I++;
- switch (op) {
- case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
- /* parse child statements, do not create new variable scope */
- oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
- while (*C->I != OP_END)
- if (!parse_child_operation(C, O, oper, GL_TRUE))
- RETURN0;
- C->I++;
- break;
- case OP_BLOCK_BEGIN_NEW_SCOPE:
- /* parse child statements, create new variable scope */
- {
- slang_output_ctx o = *O;
-
- oper->type = SLANG_OPER_BLOCK_NEW_SCOPE;
- o.vars = oper->locals;
- while (*C->I != OP_END)
- if (!parse_child_operation(C, &o, oper, GL_TRUE))
- RETURN0;
- C->I++;
- }
- break;
- case OP_DECLARE:
- /* local variable declaration, individual declarators are stored as
- * children identifiers
- */
- oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
- {
- const unsigned int first_var = O->vars->num_variables;
-
- /* parse the declaration, note that there can be zero or more
- * than one declarators
- */
- if (!parse_declaration(C, O))
- RETURN0;
- if (first_var < O->vars->num_variables) {
- const unsigned int num_vars = O->vars->num_variables - first_var;
- unsigned int i;
- assert(oper->num_children == 0);
- oper->num_children = num_vars;
- oper->children = slang_operation_new(num_vars);
- if (oper->children == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- for (i = first_var; i < O->vars->num_variables; i++) {
- slang_operation *o = &oper->children[i - first_var];
- slang_variable *var = O->vars->variables[i];
- o->type = SLANG_OPER_VARIABLE_DECL;
- o->locals->outer_scope = O->vars;
- o->a_id = var->a_name;
-
- /* new/someday...
- calculate_var_size(C, O, var);
- */
-
- if (!legal_identifier(o->a_id)) {
- slang_info_log_error(C->L, "illegal variable name '%s'",
- (char *) o->a_id);
- RETURN0;
- }
- }
- }
- }
- break;
- case OP_ASM:
- /* the __asm statement, parse the mnemonic and all its arguments
- * as expressions
- */
- oper->type = SLANG_OPER_ASM;
- oper->a_id = parse_identifier(C);
- if (oper->a_id == SLANG_ATOM_NULL)
- RETURN0;
- while (*C->I != OP_END) {
- if (!parse_child_operation(C, O, oper, GL_FALSE))
- RETURN0;
- }
- C->I++;
- break;
- case OP_BREAK:
- oper->type = SLANG_OPER_BREAK;
- break;
- case OP_CONTINUE:
- oper->type = SLANG_OPER_CONTINUE;
- break;
- case OP_DISCARD:
- oper->type = SLANG_OPER_DISCARD;
- break;
- case OP_RETURN:
- oper->type = SLANG_OPER_RETURN;
- if (!parse_child_operation(C, O, oper, GL_FALSE))
- RETURN0;
- break;
- case OP_EXPRESSION:
- oper->type = SLANG_OPER_EXPRESSION;
- if (!parse_child_operation(C, O, oper, GL_FALSE))
- RETURN0;
- break;
- case OP_IF:
- oper->type = SLANG_OPER_IF;
- if (!parse_child_operation(C, O, oper, GL_FALSE))
- RETURN0;
- if (!parse_child_operation(C, O, oper, GL_TRUE))
- RETURN0;
- if (!parse_child_operation(C, O, oper, GL_TRUE))
- RETURN0;
- break;
- case OP_WHILE:
- {
- slang_output_ctx o = *O;
-
- oper->type = SLANG_OPER_WHILE;
- o.vars = oper->locals;
- if (!parse_child_operation(C, &o, oper, GL_TRUE))
- RETURN0;
- if (!parse_child_operation(C, &o, oper, GL_TRUE))
- RETURN0;
- }
- break;
- case OP_DO:
- oper->type = SLANG_OPER_DO;
- if (!parse_child_operation(C, O, oper, GL_TRUE))
- RETURN0;
- if (!parse_child_operation(C, O, oper, GL_FALSE))
- RETURN0;
- break;
- case OP_FOR:
- {
- slang_output_ctx o = *O;
-
- oper->type = SLANG_OPER_FOR;
- o.vars = oper->locals;
- if (!parse_child_operation(C, &o, oper, GL_TRUE))
- RETURN0;
- if (!parse_child_operation(C, &o, oper, GL_TRUE))
- RETURN0;
- if (!parse_child_operation(C, &o, oper, GL_FALSE))
- RETURN0;
- if (!parse_child_operation(C, &o, oper, GL_TRUE))
- RETURN0;
- }
- break;
- case OP_PRECISION:
- {
- /* set default precision for a type in this scope */
- /* ignored at this time */
- int prec_qual = *C->I++;
- int datatype = *C->I++;
- (void) prec_qual;
- (void) datatype;
- }
- break;
- default:
- /*printf("Unexpected operation %d\n", op);*/
- RETURN0;
- }
- return 1;
-}
-
-static int
-handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
- slang_operation ** ops, unsigned int *total_ops,
- unsigned int n)
-{
- unsigned int i;
-
- op->children = slang_operation_new(n);
- if (op->children == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- op->num_children = n;
-
- for (i = 0; i < n; i++) {
- slang_operation_destruct(&op->children[i]);
- op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
- }
-
- (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
- *total_ops -= n;
-
- *ops = (slang_operation *)
- _slang_realloc(*ops,
- (*total_ops + n) * sizeof(slang_operation),
- *total_ops * sizeof(slang_operation));
- if (*ops == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- return 1;
-}
-
-static int
-is_constructor_name(const char *name, slang_atom a_name,
- slang_struct_scope * structs)
-{
- if (slang_type_specifier_type_from_string(name) != SLANG_SPEC_VOID)
- return 1;
- return slang_struct_scope_find(structs, a_name, 1) != NULL;
-}
-
-#define FUNCTION_CALL_NONARRAY 0
-#define FUNCTION_CALL_ARRAY 1
-
-static int
-parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
- slang_operation * oper)
-{
- slang_operation *ops = NULL;
- unsigned int num_ops = 0;
- int number;
-
- while (*C->I != OP_END) {
- slang_operation *op;
- const unsigned int op_code = *C->I++;
-
- /* allocate default operation, becomes a no-op if not used */
- ops = (slang_operation *)
- _slang_realloc(ops,
- num_ops * sizeof(slang_operation),
- (num_ops + 1) * sizeof(slang_operation));
- if (ops == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- op = &ops[num_ops];
- if (!slang_operation_construct(op)) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- num_ops++;
- op->locals->outer_scope = O->vars;
-
- switch (op_code) {
- case OP_PUSH_VOID:
- op->type = SLANG_OPER_VOID;
- break;
- case OP_PUSH_BOOL:
- op->type = SLANG_OPER_LITERAL_BOOL;
- if (!parse_number(C, &number))
- RETURN0;
- op->literal[0] =
- op->literal[1] =
- op->literal[2] =
- op->literal[3] = (GLfloat) number;
- op->literal_size = 1;
- break;
- case OP_PUSH_INT:
- op->type = SLANG_OPER_LITERAL_INT;
- if (!parse_number(C, &number))
- RETURN0;
- op->literal[0] =
- op->literal[1] =
- op->literal[2] =
- op->literal[3] = (GLfloat) number;
- op->literal_size = 1;
- break;
- case OP_PUSH_FLOAT:
- op->type = SLANG_OPER_LITERAL_FLOAT;
- if (!parse_float(C, &op->literal[0]))
- RETURN0;
- op->literal[1] =
- op->literal[2] =
- op->literal[3] = op->literal[0];
- op->literal_size = 1;
- break;
- case OP_PUSH_IDENTIFIER:
- op->type = SLANG_OPER_IDENTIFIER;
- op->a_id = parse_identifier(C);
- if (op->a_id == SLANG_ATOM_NULL)
- RETURN0;
- break;
- case OP_SEQUENCE:
- op->type = SLANG_OPER_SEQUENCE;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_ASSIGN:
- op->type = SLANG_OPER_ASSIGN;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_ADDASSIGN:
- op->type = SLANG_OPER_ADDASSIGN;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_SUBASSIGN:
- op->type = SLANG_OPER_SUBASSIGN;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_MULASSIGN:
- op->type = SLANG_OPER_MULASSIGN;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_DIVASSIGN:
- op->type = SLANG_OPER_DIVASSIGN;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- /*case OP_MODASSIGN: */
- /*case OP_LSHASSIGN: */
- /*case OP_RSHASSIGN: */
- /*case OP_ORASSIGN: */
- /*case OP_XORASSIGN: */
- /*case OP_ANDASSIGN: */
- case OP_SELECT:
- op->type = SLANG_OPER_SELECT;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 3))
- RETURN0;
- break;
- case OP_LOGICALOR:
- op->type = SLANG_OPER_LOGICALOR;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_LOGICALXOR:
- op->type = SLANG_OPER_LOGICALXOR;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_LOGICALAND:
- op->type = SLANG_OPER_LOGICALAND;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- /*case OP_BITOR: */
- /*case OP_BITXOR: */
- /*case OP_BITAND: */
- case OP_EQUAL:
- op->type = SLANG_OPER_EQUAL;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_NOTEQUAL:
- op->type = SLANG_OPER_NOTEQUAL;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_LESS:
- op->type = SLANG_OPER_LESS;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_GREATER:
- op->type = SLANG_OPER_GREATER;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_LESSEQUAL:
- op->type = SLANG_OPER_LESSEQUAL;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_GREATEREQUAL:
- op->type = SLANG_OPER_GREATEREQUAL;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- /*case OP_LSHIFT: */
- /*case OP_RSHIFT: */
- case OP_ADD:
- op->type = SLANG_OPER_ADD;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_SUBTRACT:
- op->type = SLANG_OPER_SUBTRACT;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_MULTIPLY:
- op->type = SLANG_OPER_MULTIPLY;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_DIVIDE:
- op->type = SLANG_OPER_DIVIDE;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- /*case OP_MODULUS: */
- case OP_PREINCREMENT:
- op->type = SLANG_OPER_PREINCREMENT;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
- RETURN0;
- break;
- case OP_PREDECREMENT:
- op->type = SLANG_OPER_PREDECREMENT;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
- RETURN0;
- break;
- case OP_PLUS:
- op->type = SLANG_OPER_PLUS;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
- RETURN0;
- break;
- case OP_MINUS:
- op->type = SLANG_OPER_MINUS;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
- RETURN0;
- break;
- case OP_NOT:
- op->type = SLANG_OPER_NOT;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
- RETURN0;
- break;
- /*case OP_COMPLEMENT: */
- case OP_SUBSCRIPT:
- op->type = SLANG_OPER_SUBSCRIPT;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
- RETURN0;
- break;
- case OP_METHOD:
- op->type = SLANG_OPER_METHOD;
- op->a_obj = parse_identifier(C);
- if (op->a_obj == SLANG_ATOM_NULL)
- RETURN0;
-
- op->a_id = parse_identifier(C);
- if (op->a_id == SLANG_ATOM_NULL)
- RETURN0;
-
- assert(*C->I == OP_END);
- C->I++;
-
- while (*C->I != OP_END)
- if (!parse_child_operation(C, O, op, GL_FALSE))
- RETURN0;
- C->I++;
-#if 0
- /* don't lookup the method (not yet anyway) */
- if (!C->parsing_builtin
- && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
- const char *id;
-
- id = slang_atom_pool_id(C->atoms, op->a_id);
- if (!is_constructor_name(id, op->a_id, O->structs)) {
- slang_info_log_error(C->L, "%s: undeclared function name.", id);
- RETURN0;
- }
- }
-#endif
- break;
- case OP_CALL:
- {
- GLboolean array_constructor = GL_FALSE;
- GLint array_constructor_size = 0;
-
- op->type = SLANG_OPER_CALL;
- op->a_id = parse_identifier(C);
- if (op->a_id == SLANG_ATOM_NULL)
- RETURN0;
- switch (*C->I++) {
- case FUNCTION_CALL_NONARRAY:
- /* Nothing to do. */
- break;
- case FUNCTION_CALL_ARRAY:
- /* Calling an array constructor. For example:
- * float[3](1.1, 2.2, 3.3);
- */
- if (!O->allow_array_types) {
- slang_info_log_error(C->L,
- "array constructors not allowed "
- "in this GLSL version");
- RETURN0;
- }
- else {
- /* parse the array constructor size */
- slang_operation array_size;
- array_constructor = GL_TRUE;
- slang_operation_construct(&array_size);
- if (!parse_expression(C, O, &array_size)) {
- slang_operation_destruct(&array_size);
- return GL_FALSE;
- }
- if (array_size.type != SLANG_OPER_LITERAL_INT) {
- slang_info_log_error(C->L,
- "constructor array size is not an integer");
- slang_operation_destruct(&array_size);
- RETURN0;
- }
- array_constructor_size = (int) array_size.literal[0];
- op->array_constructor = GL_TRUE;
- slang_operation_destruct(&array_size);
- }
- break;
- default:
- assert(0);
- RETURN0;
- }
- while (*C->I != OP_END)
- if (!parse_child_operation(C, O, op, GL_FALSE))
- RETURN0;
- C->I++;
-
- if (array_constructor &&
- array_constructor_size != op->num_children) {
- slang_info_log_error(C->L, "number of parameters to array"
- " constructor does not match array size");
- RETURN0;
- }
-
- if (!C->parsing_builtin
- && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
- const char *id;
-
- id = slang_atom_pool_id(C->atoms, op->a_id);
- if (!is_constructor_name(id, op->a_id, O->structs)) {
- slang_info_log_error(C->L, "%s: undeclared function name.", id);
- RETURN0;
- }
- }
- }
- break;
- case OP_FIELD:
- op->type = SLANG_OPER_FIELD;
- op->a_id = parse_identifier(C);
- if (op->a_id == SLANG_ATOM_NULL)
- RETURN0;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
- RETURN0;
- break;
- case OP_POSTINCREMENT:
- op->type = SLANG_OPER_POSTINCREMENT;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
- RETURN0;
- break;
- case OP_POSTDECREMENT:
- op->type = SLANG_OPER_POSTDECREMENT;
- if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
- RETURN0;
- break;
- default:
- RETURN0;
- }
- }
- C->I++;
-
- slang_operation_destruct(oper);
- *oper = *ops; /* struct copy */
- _slang_free(ops);
-
- return 1;
-}
-
-/* function parameter array presence */
-#define PARAMETER_ARRAY_NOT_PRESENT 0
-#define PARAMETER_ARRAY_PRESENT 1
-
-static int
-parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
- slang_variable * param)
-{
- int param_qual, precision_qual;
-
- /* parse and validate the parameter's type qualifiers (there can be
- * two at most) because not all combinations are valid
- */
- if (!parse_type_qualifier(C, &param->type.qualifier))
- RETURN0;
-
- param_qual = *C->I++;
- switch (param_qual) {
- case PARAM_QUALIFIER_IN:
- if (param->type.qualifier != SLANG_QUAL_CONST
- && param->type.qualifier != SLANG_QUAL_NONE) {
- slang_info_log_error(C->L, "Invalid type qualifier.");
- RETURN0;
- }
- break;
- case PARAM_QUALIFIER_OUT:
- if (param->type.qualifier == SLANG_QUAL_NONE)
- param->type.qualifier = SLANG_QUAL_OUT;
- else {
- slang_info_log_error(C->L, "Invalid type qualifier.");
- RETURN0;
- }
- break;
- case PARAM_QUALIFIER_INOUT:
- if (param->type.qualifier == SLANG_QUAL_NONE)
- param->type.qualifier = SLANG_QUAL_INOUT;
- else {
- slang_info_log_error(C->L, "Invalid type qualifier.");
- RETURN0;
- }
- break;
- case PARAM_QUALIFIER_NONE:
- /* like IN but doesn't throw error */
- break;
- default:
- RETURN0;
- }
-
- /* parse precision qualifier (lowp, mediump, highp */
- precision_qual = *C->I++;
- /* ignored at this time */
- (void) precision_qual;
-
- /* parse parameter's type specifier and name */
- if (!parse_type_specifier(C, O, &param->type.specifier))
- RETURN0;
- if (!parse_type_array_size(C, O, &param->type.array_len))
- RETURN0;
- param->a_name = parse_identifier(C);
- if (param->a_name == SLANG_ATOM_NULL)
- RETURN0;
-
- /* first-class array
- */
- if (param->type.array_len >= 0) {
- slang_type_specifier p;
-
- slang_type_specifier_ctr(&p);
- if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
- slang_type_specifier_dtr(&p);
- RETURN0;
- }
- if (!convert_to_array(C, param, &p)) {
- slang_type_specifier_dtr(&p);
- RETURN0;
- }
- slang_type_specifier_dtr(&p);
- param->array_len = param->type.array_len;
- }
-
- /* if the parameter is an array, parse its size (the size must be
- * explicitly defined
- */
- if (*C->I++ == PARAMETER_ARRAY_PRESENT) {
- slang_type_specifier p;
-
- if (param->type.array_len >= 0) {
- slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
- RETURN0;
- }
- slang_type_specifier_ctr(&p);
- if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
- slang_type_specifier_dtr(&p);
- RETURN0;
- }
- if (!convert_to_array(C, param, &p)) {
- slang_type_specifier_dtr(&p);
- RETURN0;
- }
- slang_type_specifier_dtr(&p);
- if (!parse_array_len(C, O, &param->array_len))
- RETURN0;
- }
-
-#if 0
- /* calculate the parameter size */
- if (!calculate_var_size(C, O, param))
- RETURN0;
-#endif
- /* TODO: allocate the local address here? */
- return 1;
-}
-
-/* function type */
-#define FUNCTION_ORDINARY 0
-#define FUNCTION_CONSTRUCTOR 1
-#define FUNCTION_OPERATOR 2
-
-/* function parameter */
-#define PARAMETER_NONE 0
-#define PARAMETER_NEXT 1
-
-/* operator type */
-#define OPERATOR_ADDASSIGN 1
-#define OPERATOR_SUBASSIGN 2
-#define OPERATOR_MULASSIGN 3
-#define OPERATOR_DIVASSIGN 4
-/*#define OPERATOR_MODASSIGN 5*/
-/*#define OPERATOR_LSHASSIGN 6*/
-/*#define OPERATOR_RSHASSIGN 7*/
-/*#define OPERATOR_ANDASSIGN 8*/
-/*#define OPERATOR_XORASSIGN 9*/
-/*#define OPERATOR_ORASSIGN 10*/
-#define OPERATOR_LOGICALXOR 11
-/*#define OPERATOR_BITOR 12*/
-/*#define OPERATOR_BITXOR 13*/
-/*#define OPERATOR_BITAND 14*/
-#define OPERATOR_LESS 15
-#define OPERATOR_GREATER 16
-#define OPERATOR_LESSEQUAL 17
-#define OPERATOR_GREATEREQUAL 18
-/*#define OPERATOR_LSHIFT 19*/
-/*#define OPERATOR_RSHIFT 20*/
-#define OPERATOR_MULTIPLY 21
-#define OPERATOR_DIVIDE 22
-/*#define OPERATOR_MODULUS 23*/
-#define OPERATOR_INCREMENT 24
-#define OPERATOR_DECREMENT 25
-#define OPERATOR_PLUS 26
-#define OPERATOR_MINUS 27
-/*#define OPERATOR_COMPLEMENT 28*/
-#define OPERATOR_NOT 29
-
-static const struct
-{
- unsigned int o_code;
- const char *o_name;
-} operator_names[] = {
- {OPERATOR_INCREMENT, "++"},
- {OPERATOR_ADDASSIGN, "+="},
- {OPERATOR_PLUS, "+"},
- {OPERATOR_DECREMENT, "--"},
- {OPERATOR_SUBASSIGN, "-="},
- {OPERATOR_MINUS, "-"},
- {OPERATOR_NOT, "!"},
- {OPERATOR_MULASSIGN, "*="},
- {OPERATOR_MULTIPLY, "*"},
- {OPERATOR_DIVASSIGN, "/="},
- {OPERATOR_DIVIDE, "/"},
- {OPERATOR_LESSEQUAL, "<="},
- /*{ OPERATOR_LSHASSIGN, "<<=" }, */
- /*{ OPERATOR_LSHIFT, "<<" }, */
- {OPERATOR_LESS, "<"},
- {OPERATOR_GREATEREQUAL, ">="},
- /*{ OPERATOR_RSHASSIGN, ">>=" }, */
- /*{ OPERATOR_RSHIFT, ">>" }, */
- {OPERATOR_GREATER, ">"},
- /*{ OPERATOR_MODASSIGN, "%=" }, */
- /*{ OPERATOR_MODULUS, "%" }, */
- /*{ OPERATOR_ANDASSIGN, "&=" }, */
- /*{ OPERATOR_BITAND, "&" }, */
- /*{ OPERATOR_ORASSIGN, "|=" }, */
- /*{ OPERATOR_BITOR, "|" }, */
- /*{ OPERATOR_COMPLEMENT, "~" }, */
- /*{ OPERATOR_XORASSIGN, "^=" }, */
- {OPERATOR_LOGICALXOR, "^^"},
- /*{ OPERATOR_BITXOR, "^" } */
-};
-
-static slang_atom
-parse_operator_name(slang_parse_ctx * C)
-{
- unsigned int i;
-
- for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) {
- if (operator_names[i].o_code == (unsigned int) (*C->I)) {
- slang_atom atom =
- slang_atom_pool_atom(C->atoms, operator_names[i].o_name);
- if (atom == SLANG_ATOM_NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- C->I++;
- return atom;
- }
- }
- RETURN0;
-}
-
-
-static int
-parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
- slang_function * func)
-{
- GLuint functype;
- /* parse function type and name */
- if (!parse_fully_specified_type(C, O, &func->header.type))
- RETURN0;
-
- functype = *C->I++;
- switch (functype) {
- case FUNCTION_ORDINARY:
- func->kind = SLANG_FUNC_ORDINARY;
- func->header.a_name = parse_identifier(C);
- if (func->header.a_name == SLANG_ATOM_NULL)
- RETURN0;
- break;
- case FUNCTION_CONSTRUCTOR:
- func->kind = SLANG_FUNC_CONSTRUCTOR;
- if (func->header.type.specifier.type == SLANG_SPEC_STRUCT)
- RETURN0;
- func->header.a_name =
- slang_atom_pool_atom(C->atoms,
- slang_type_specifier_type_to_string
- (func->header.type.specifier.type));
- if (func->header.a_name == SLANG_ATOM_NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- break;
- case FUNCTION_OPERATOR:
- func->kind = SLANG_FUNC_OPERATOR;
- func->header.a_name = parse_operator_name(C);
- if (func->header.a_name == SLANG_ATOM_NULL)
- RETURN0;
- break;
- default:
- RETURN0;
- }
-
- if (!legal_identifier(func->header.a_name)) {
- slang_info_log_error(C->L, "illegal function name '%s'",
- (char *) func->header.a_name);
- RETURN0;
- }
-
- /* parse function parameters */
- while (*C->I++ == PARAMETER_NEXT) {
- slang_variable *p = slang_variable_scope_grow(func->parameters);
- if (!p) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- if (!parse_parameter_declaration(C, O, p))
- RETURN0;
- }
-
- /* if the function returns a value, append a hidden __retVal 'out'
- * parameter that corresponds to the return value.
- */
- if (_slang_function_has_return_value(func)) {
- slang_variable *p = slang_variable_scope_grow(func->parameters);
- slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal");
- assert(a_retVal);
- p->a_name = a_retVal;
- p->type = func->header.type;
- p->type.qualifier = SLANG_QUAL_OUT;
- }
-
- /* function formal parameters and local variables share the same
- * scope, so save the information about param count in a seperate
- * place also link the scope to the global variable scope so when a
- * given identifier is not found here, the search process continues
- * in the global space
- */
- func->param_count = func->parameters->num_variables;
- func->parameters->outer_scope = O->vars;
-
- return 1;
-}
-
-static int
-parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
- slang_function * func)
-{
- slang_output_ctx o = *O;
-
- if (!parse_function_prototype(C, O, func))
- RETURN0;
-
- /* create function's body operation */
- func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation));
- if (func->body == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- if (!slang_operation_construct(func->body)) {
- _slang_free(func->body);
- func->body = NULL;
- slang_info_log_memory(C->L);
- RETURN0;
- }
-
- /* to parse the body the parse context is modified in order to
- * capture parsed variables into function's local variable scope
- */
- C->global_scope = GL_FALSE;
- o.vars = func->parameters;
- if (!parse_statement(C, &o, func->body))
- RETURN0;
-
- C->global_scope = GL_TRUE;
- return 1;
-}
-
-static GLboolean
-initialize_global(slang_assemble_ctx * A, slang_variable * var)
-{
- slang_operation op_id, op_assign;
- GLboolean result;
-
- /* construct the left side of assignment */
- if (!slang_operation_construct(&op_id))
- return GL_FALSE;
- op_id.type = SLANG_OPER_IDENTIFIER;
- op_id.a_id = var->a_name;
-
- /* put the variable into operation's scope */
- op_id.locals->variables =
- (slang_variable **) _slang_alloc(sizeof(slang_variable *));
- if (op_id.locals->variables == NULL) {
- slang_operation_destruct(&op_id);
- return GL_FALSE;
- }
- op_id.locals->num_variables = 1;
- op_id.locals->variables[0] = var;
-
- /* construct the assignment expression */
- if (!slang_operation_construct(&op_assign)) {
- op_id.locals->num_variables = 0;
- slang_operation_destruct(&op_id);
- return GL_FALSE;
- }
- op_assign.type = SLANG_OPER_ASSIGN;
- op_assign.children =
- (slang_operation *) _slang_alloc(2 * sizeof(slang_operation));
- if (op_assign.children == NULL) {
- slang_operation_destruct(&op_assign);
- op_id.locals->num_variables = 0;
- slang_operation_destruct(&op_id);
- return GL_FALSE;
- }
- op_assign.num_children = 2;
- op_assign.children[0] = op_id;
- op_assign.children[1] = *var->initializer;
-
- result = 1;
-
- /* carefully destroy the operations */
- op_assign.num_children = 0;
- _slang_free(op_assign.children);
- op_assign.children = NULL;
- slang_operation_destruct(&op_assign);
- op_id.locals->num_variables = 0;
- slang_operation_destruct(&op_id);
-
- if (!result)
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-/* init declarator list */
-#define DECLARATOR_NONE 0
-#define DECLARATOR_NEXT 1
-
-/* variable declaration */
-#define VARIABLE_NONE 0
-#define VARIABLE_IDENTIFIER 1
-#define VARIABLE_INITIALIZER 2
-#define VARIABLE_ARRAY_EXPLICIT 3
-#define VARIABLE_ARRAY_UNKNOWN 4
-
-
-/**
- * Check if it's OK to re-declare a variable with the given new type.
- * This happens when applying layout qualifiers to gl_FragCoord or
- * (re)setting an array size.
- * If redeclaration is OK, return a pointer to the incoming variable
- * updated with new type info. Else return NULL;
- */
-static slang_variable *
-redeclare_variable(slang_variable *var,
- const slang_fully_specified_type *type)
-{
- if (slang_fully_specified_types_compatible(&var->type, type)) {
- /* replace orig var layout with new layout */
- var->type.layout = type->layout;
-
- /* XXX there may be other type updates in the future here */
-
- return var;
- }
- else
- return NULL;
-}
-
-
-/**
- * Parse the initializer for a variable declaration.
- */
-static int
-parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
- const slang_fully_specified_type * type)
-{
- GET_CURRENT_CONTEXT(ctx); /* a hack */
- slang_variable *var = NULL, *prevDecl;
- slang_atom a_name;
-
- /* empty init declatator (without name, e.g. "float ;") */
- if (*C->I++ == VARIABLE_NONE)
- return 1;
-
- a_name = parse_identifier(C);
-
- /* check if name is already in this scope */
- prevDecl = _slang_variable_locate(O->vars, a_name, C->global_scope);
- if (prevDecl) {
- /* A var with this name has already been declared.
- * Check if redeclaring the var with a different type/layout is legal.
- */
- if (C->global_scope) {
- var = redeclare_variable(prevDecl, type);
- }
- if (!var) {
- slang_info_log_error(C->L,
- "declaration of '%s' conflicts with previous declaration",
- (char *) a_name);
- RETURN0;
- }
- }
-
- if (!var) {
- /* make room for a new variable and initialize it */
- var = slang_variable_scope_grow(O->vars);
- if (!var) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
-
- /* copy the declarator type qualifier/etc info, parse the identifier */
- var->type.qualifier = type->qualifier;
- var->type.centroid = type->centroid;
- var->type.precision = type->precision;
- var->type.specifier = type->specifier;/*new*/
- var->type.variant = type->variant;
- var->type.layout = type->layout;
- var->type.array_len = type->array_len;
- var->type.varying_kind = type->varying_kind;
- var->a_name = a_name;
- if (var->a_name == SLANG_ATOM_NULL)
- RETURN0;
- }
-
- switch (*C->I++) {
- case VARIABLE_NONE:
- /* simple variable declarator - just copy the specifier */
- if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
- RETURN0;
- break;
- case VARIABLE_INITIALIZER:
- /* initialized variable - copy the specifier and parse the expression */
- if (0 && type->array_len >= 0) {
- /* The type was something like "float[4]" */
- convert_to_array(C, var, &type->specifier);
- var->array_len = type->array_len;
- }
- else {
- if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
- RETURN0;
- }
- var->initializer =
- (slang_operation *) _slang_alloc(sizeof(slang_operation));
- if (var->initializer == NULL) {
- slang_info_log_memory(C->L);
- RETURN0;
- }
- if (!slang_operation_construct(var->initializer)) {
- _slang_free(var->initializer);
- var->initializer = NULL;
- slang_info_log_memory(C->L);
- RETURN0;
- }
- if (!parse_expression(C, O, var->initializer))
- RETURN0;
- break;
- case VARIABLE_ARRAY_UNKNOWN:
- /* unsized array - mark it as array and copy the specifier to
- * the array element
- */
- if (type->array_len >= 0) {
- slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
- RETURN0;
- }
- if (!convert_to_array(C, var, &type->specifier))
- return GL_FALSE;
- break;
- case VARIABLE_ARRAY_EXPLICIT:
- if (type->array_len >= 0) {
- /* the user is trying to do something like: float[2] x[3]; */
- slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
- RETURN0;
- }
- if (!convert_to_array(C, var, &type->specifier))
- return GL_FALSE;
- if (!parse_array_len(C, O, &var->array_len))
- return GL_FALSE;
- break;
- default:
- RETURN0;
- }
-
- /* allocate global address space for a variable with a known size */
- if (C->global_scope
- && !(var->type.specifier.type == SLANG_SPEC_ARRAY
- && var->array_len == 0)) {
- if (!calculate_var_size(C, O, var))
- return GL_FALSE;
- }
-
- /* emit code for global var decl */
- if (C->global_scope) {
- slang_assemble_ctx A;
- memset(&A, 0, sizeof(slang_assemble_ctx));
- A.allow_uniform_initializers = C->version > 110;
- A.atoms = C->atoms;
- A.space.funcs = O->funs;
- A.space.structs = O->structs;
- A.space.vars = O->vars;
- A.program = O->program;
- A.pragmas = O->pragmas;
- A.vartable = O->vartable;
- A.log = C->L;
- A.curFuncEndLabel = NULL;
- A.EmitContReturn = ctx->Shader.EmitContReturn;
- if (!_slang_codegen_global_variable(&A, var, C->type))
- RETURN0;
- }
-
- /* initialize global variable */
- if (C->global_scope) {
- if (var->initializer != NULL) {
- slang_assemble_ctx A;
- memset(&A, 0, sizeof(slang_assemble_ctx));
- A.allow_uniform_initializers = C->version > 110;
- A.atoms = C->atoms;
- A.space.funcs = O->funs;
- A.space.structs = O->structs;
- A.space.vars = O->vars;
- if (!initialize_global(&A, var))
- RETURN0;
- }
- }
-
- if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT &&
- var->a_name == slang_atom_pool_atom(C->atoms, "gl_FragCoord")) {
- /* set the program's PixelCenterInteger, OriginUpperLeft fields */
- struct gl_fragment_program *fragProg =
- (struct gl_fragment_program *) O->program;
-
- if (var->type.layout & SLANG_LAYOUT_UPPER_LEFT_BIT) {
- fragProg->OriginUpperLeft = GL_TRUE;
- }
- if (var->type.layout & SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT) {
- fragProg->PixelCenterInteger = GL_TRUE;
- }
- }
-
- return 1;
-}
-
-/**
- * Parse a list of variable declarations. Each variable may have an
- * initializer.
- */
-static int
-parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
-{
- slang_fully_specified_type type;
-
- /* parse the fully specified type, common to all declarators */
- if (!slang_fully_specified_type_construct(&type))
- RETURN0;
- if (!parse_fully_specified_type(C, O, &type)) {
- slang_fully_specified_type_destruct(&type);
- RETURN0;
- }
-
- /* parse declarators, pass-in the parsed type */
- do {
- if (!parse_init_declarator(C, O, &type)) {
- slang_fully_specified_type_destruct(&type);
- RETURN0;
- }
- }
- while (*C->I++ == DECLARATOR_NEXT);
-
- slang_fully_specified_type_destruct(&type);
- return 1;
-}
-
-
-/**
- * Parse a function definition or declaration.
- * \param C parsing context
- * \param O output context
- * \param definition if non-zero expect a definition, else a declaration
- * \param parsed_func_ret returns the parsed function
- * \return GL_TRUE if success, GL_FALSE if failure
- */
-static GLboolean
-parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
- slang_function ** parsed_func_ret)
-{
- slang_function parsed_func, *found_func;
-
- /* parse function definition/declaration */
- if (!slang_function_construct(&parsed_func))
- return GL_FALSE;
- if (definition) {
- if (!parse_function_definition(C, O, &parsed_func)) {
- slang_function_destruct(&parsed_func);
- return GL_FALSE;
- }
- }
- else {
- if (!parse_function_prototype(C, O, &parsed_func)) {
- slang_function_destruct(&parsed_func);
- return GL_FALSE;
- }
- }
-
- /* find a function with a prototype matching the parsed one - only
- * the current scope is being searched to allow built-in function
- * overriding
- */
- found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
- if (found_func == NULL) {
- /* New function, add it to the function list */
- O->funs->functions =
- (slang_function *) _slang_realloc(O->funs->functions,
- O->funs->num_functions
- * sizeof(slang_function),
- (O->funs->num_functions + 1)
- * sizeof(slang_function));
- if (O->funs->functions == NULL) {
- /* Make sure that there are no functions marked, as the
- * allocation is currently NULL, in order to avoid
- * a potental segfault as we clean up later.
- */
- O->funs->num_functions = 0;
-
- slang_info_log_memory(C->L);
- slang_function_destruct(&parsed_func);
- return GL_FALSE;
- }
- O->funs->functions[O->funs->num_functions] = parsed_func;
- O->funs->num_functions++;
-
- /* return the newly parsed function */
- *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
- }
- else {
- /* previously defined or declared */
- /* TODO: check function return type qualifiers and specifiers */
- if (definition) {
- if (found_func->body != NULL) {
- slang_info_log_error(C->L, "%s: function already has a body.",
- slang_atom_pool_id(C->atoms,
- parsed_func.header.
- a_name));
- slang_function_destruct(&parsed_func);
- return GL_FALSE;
- }
-
- /* destroy the existing function declaration and replace it
- * with the new one
- */
- slang_function_destruct(found_func);
- *found_func = parsed_func;
- }
- else {
- /* another declaration of the same function prototype - ignore it */
- slang_function_destruct(&parsed_func);
- }
-
- /* return the found function */
- *parsed_func_ret = found_func;
- }
-
- return GL_TRUE;
-}
-
-/* declaration */
-#define DECLARATION_FUNCTION_PROTOTYPE 1
-#define DECLARATION_INIT_DECLARATOR_LIST 2
-
-static int
-parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
-{
- switch (*C->I++) {
- case DECLARATION_INIT_DECLARATOR_LIST:
- if (!parse_init_declarator_list(C, O))
- RETURN0;
- break;
- case DECLARATION_FUNCTION_PROTOTYPE:
- {
- slang_function *dummy_func;
-
- if (!parse_function(C, O, 0, &dummy_func))
- RETURN0;
- }
- break;
- default:
- RETURN0;
- }
- return 1;
-}
-
-static int
-parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O)
-{
- int precision, type;
-
- if (!O->allow_precision) {
- slang_info_log_error(C->L, "syntax error at \"precision\"");
- RETURN0;
- }
-
- precision = *C->I++;
- switch (precision) {
- case PRECISION_LOW:
- case PRECISION_MEDIUM:
- case PRECISION_HIGH:
- /* OK */
- break;
- default:
- _mesa_problem(NULL, "unexpected precision %d at %s:%d\n",
- precision, __FILE__, __LINE__);
- RETURN0;
- }
-
- type = *C->I++;
- switch (type) {
- case TYPE_SPECIFIER_FLOAT:
- case TYPE_SPECIFIER_INT:
- case TYPE_SPECIFIER_SAMPLER1D:
- case TYPE_SPECIFIER_SAMPLER2D:
- case TYPE_SPECIFIER_SAMPLER3D:
- case TYPE_SPECIFIER_SAMPLERCUBE:
- case TYPE_SPECIFIER_SAMPLER1DSHADOW:
- case TYPE_SPECIFIER_SAMPLER2DSHADOW:
- case TYPE_SPECIFIER_SAMPLER2DRECT:
- case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
- case TYPE_SPECIFIER_SAMPLER_1D_ARRAY:
- case TYPE_SPECIFIER_SAMPLER_2D_ARRAY:
- case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW:
- case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW:
- /* OK */
- break;
- default:
- _mesa_problem(NULL, "unexpected type %d at %s:%d\n",
- type, __FILE__, __LINE__);
- RETURN0;
- }
-
- assert(type < TYPE_SPECIFIER_COUNT);
- O->default_precision[type] = precision;
-
- return 1;
-}
-
-
-/**
- * Initialize the default precision for all types.
- * XXX this info isn't used yet.
- */
-static void
-init_default_precision(slang_output_ctx *O, slang_unit_type type)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLuint i;
- for (i = 0; i < TYPE_SPECIFIER_COUNT; i++) {
-#if FEATURE_es2_glsl
- if (ctx->API == API_OPENGLES2)
- O->default_precision[i] = PRECISION_LOW;
- else
- O->default_precision[i] = PRECISION_HIGH;
-#else
- (void) ctx;
- O->default_precision[i] = PRECISION_HIGH;
-#endif
- }
-
- if (type == SLANG_UNIT_VERTEX_SHADER || type == SLANG_UNIT_GEOMETRY_SHADER) {
- O->default_precision[TYPE_SPECIFIER_FLOAT] = PRECISION_HIGH;
- O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_HIGH;
- }
- else {
- O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM;
- }
-}
-
-
-static int
-parse_invariant(slang_parse_ctx * C, slang_output_ctx * O)
-{
- if (O->allow_invariant) {
- slang_atom *a = parse_identifier(C);
- /* XXX not doing anything with this var yet */
- /*printf("ID: %s\n", (char*) a);*/
- return a ? 1 : 0;
- }
- else {
- slang_info_log_error(C->L, "syntax error at \"invariant\"");
- RETURN0;
- }
-}
-
-
-/* external declaration or default precision specifier */
-#define EXTERNAL_NULL 0
-#define EXTERNAL_FUNCTION_DEFINITION 1
-#define EXTERNAL_DECLARATION 2
-#define DEFAULT_PRECISION 3
-#define INVARIANT_STMT 4
-
-
-static GLboolean
-parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
- struct gl_shader *shader)
-{
- GET_CURRENT_CONTEXT(ctx);
- slang_output_ctx o;
- GLboolean success;
- GLuint maxRegs;
- slang_function *mainFunc = NULL;
-
- if (unit->type == SLANG_UNIT_FRAGMENT_BUILTIN ||
- unit->type == SLANG_UNIT_FRAGMENT_SHADER) {
- maxRegs = ctx->Const.FragmentProgram.MaxTemps;
- }
- else if (unit->type == SLANG_UNIT_VERTEX_BUILTIN ||
- unit->type == SLANG_UNIT_VERTEX_SHADER) {
- maxRegs = ctx->Const.VertexProgram.MaxTemps;
- } else {
- assert(unit->type == SLANG_UNIT_GEOMETRY_BUILTIN ||
- unit->type == SLANG_UNIT_GEOMETRY_SHADER);
- maxRegs = ctx->Const.GeometryProgram.MaxTemps;
- }
-
- /* setup output context */
- o.funs = &unit->funs;
- o.structs = &unit->structs;
- o.vars = &unit->vars;
- o.program = shader ? shader->Program : NULL;
- o.pragmas = shader ? &shader->Pragmas : NULL;
- o.vartable = _slang_new_var_table(maxRegs);
- _slang_push_var_table(o.vartable);
-
- /* allow 'invariant' keyword? */
-#if FEATURE_es2_glsl
- o.allow_invariant =
- (ctx->API == API_OPENGLES2 || C->version >= 120) ? GL_TRUE : GL_FALSE;
-#else
- o.allow_invariant = (C->version >= 120) ? GL_TRUE : GL_FALSE;
-#endif
-
- /* allow 'centroid' keyword? */
- o.allow_centroid = (C->version >= 120) ? GL_TRUE : GL_FALSE;
-
- /* allow 'lowp/mediump/highp' keywords? */
-#if FEATURE_es2_glsl
- o.allow_precision =
- (ctx->API == API_OPENGLES2 || C->version >= 120) ? GL_TRUE : GL_FALSE;
-#else
- o.allow_precision = (C->version >= 120) ? GL_TRUE : GL_FALSE;
-#endif
- init_default_precision(&o, unit->type);
-
- /* allow 'float[]' keyword? */
- o.allow_array_types = (C->version >= 120) ? GL_TRUE : GL_FALSE;
-
- /* parse individual functions and declarations */
- while (*C->I != EXTERNAL_NULL) {
- switch (*C->I++) {
- case EXTERNAL_FUNCTION_DEFINITION:
- {
- slang_function *func;
- success = parse_function(C, &o, 1, &func);
- if (success && strcmp((char *) func->header.a_name, "main") == 0) {
- /* found main() */
- mainFunc = func;
- }
- }
- break;
- case EXTERNAL_DECLARATION:
- success = parse_declaration(C, &o);
- break;
- case DEFAULT_PRECISION:
- success = parse_default_precision(C, &o);
- break;
- case INVARIANT_STMT:
- success = parse_invariant(C, &o);
- break;
- default:
- success = GL_FALSE;
- }
-
- if (!success) {
- /* xxx free codegen */
- _slang_pop_var_table(o.vartable);
- return GL_FALSE;
- }
- }
- C->I++;
-
- if (mainFunc) {
- /* assemble (generate code) for main() */
- slang_assemble_ctx A;
- memset(&A, 0, sizeof(slang_assemble_ctx));
- A.atoms = C->atoms;
- A.space.funcs = o.funs;
- A.space.structs = o.structs;
- A.space.vars = o.vars;
- A.program = o.program;
- A.pragmas = &shader->Pragmas;
- A.vartable = o.vartable;
- A.EmitContReturn = ctx->Shader.EmitContReturn;
- A.log = C->L;
- A.allow_uniform_initializers = C->version > 110;
-
- /* main() takes no parameters */
- if (mainFunc->param_count > 0) {
- slang_info_log_error(A.log, "main() takes no arguments");
- return GL_FALSE;
- }
-
- _slang_codegen_function(&A, mainFunc);
-
- shader->Main = GL_TRUE; /* this shader defines main() */
-
- shader->UnresolvedRefs = A.UnresolvedRefs;
- }
-
- _slang_pop_var_table(o.vartable);
- _slang_delete_var_table(o.vartable);
-
- return GL_TRUE;
-}
-
-static GLboolean
-compile_binary(const unsigned char * prod, slang_code_unit * unit,
- GLuint version,
- slang_unit_type type, slang_info_log * infolog,
- slang_code_unit * builtin, slang_code_unit * downlink,
- struct gl_shader *shader)
-{
- slang_parse_ctx C;
-
- unit->type = type;
-
- /* setup parse context */
- C.I = prod;
- C.L = infolog;
- C.parsing_builtin = (builtin == NULL);
- C.global_scope = GL_TRUE;
- C.atoms = &unit->object->atompool;
- C.type = type;
- C.version = version;
-
- if (!check_revision(&C))
- return GL_FALSE;
-
- if (downlink != NULL) {
- unit->vars.outer_scope = &downlink->vars;
- unit->funs.outer_scope = &downlink->funs;
- unit->structs.outer_scope = &downlink->structs;
- }
-
- /* parse translation unit */
- return parse_code_unit(&C, unit, shader);
-}
-
-static GLboolean
-compile_with_grammar(const char *source,
- slang_code_unit *unit,
- slang_unit_type type,
- slang_info_log *infolog,
- slang_code_unit *builtin,
- struct gl_shader *shader,
- struct gl_sl_pragmas *pragmas,
- unsigned int shader_type,
- unsigned int parsing_builtin)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct sl_pp_purify_options options;
- struct sl_pp_context *context;
- unsigned char *prod;
- GLuint size;
- unsigned int version;
- unsigned int maxVersion;
- int result;
- char errmsg[200] = "";
-
- assert(shader_type == 1 || shader_type == 2);
-
- memset(&options, 0, sizeof(options));
-
- context = sl_pp_context_create(source, &options);
- if (!context) {
- slang_info_log_error(infolog, "out of memory");
- return GL_FALSE;
- }
-
- if (sl_pp_version(context, &version)) {
- slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
- sl_pp_context_destroy(context);
- return GL_FALSE;
- }
-
- if (sl_pp_context_add_extension(context, "GL_ARB_draw_buffers") ||
- sl_pp_context_add_extension(context, "GL_ARB_texture_rectangle")) {
- slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
- sl_pp_context_destroy(context);
- return GL_FALSE;
- }
-
- if (type == SLANG_UNIT_FRAGMENT_SHADER) {
- sl_pp_context_add_extension(context, "GL_ARB_fragment_coord_conventions");
- }
-
-
-#if FEATURE_es2_glsl
- if (ctx->API == API_OPENGLES2) {
- if (sl_pp_context_add_predefined(context, "GL_ES", "1") ||
- sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) {
- slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
- sl_pp_context_destroy(context);
- return GL_FALSE;
- }
- }
-#else
- (void) ctx;
-#endif
-
-#if FEATURE_ARB_shading_language_120
- maxVersion = 120;
-#elif FEATURE_es2_glsl
- maxVersion = 100;
-#else
- maxVersion = 110;
-#endif
-
- if (version > maxVersion ||
- (version != 100 && version != 110 && version != 120)) {
- slang_info_log_error(infolog,
- "language version %.2f is not supported.",
- version * 0.01);
- sl_pp_context_destroy(context);
- return GL_FALSE;
- }
-
- /* Finally check the syntax and generate its binary representation. */
- result = sl_cl_compile(context,
- shader_type,
- parsing_builtin,
- &prod,
- &size,
- errmsg,
- sizeof(errmsg));
-
- sl_pp_context_destroy(context);
-
- if (result) {
- /*GLint pos;*/
-
- slang_info_log_error(infolog, errmsg);
- /* syntax error (possibly in library code) */
-#if 0
- {
- int line, col;
- char *s;
- s = (char *) _mesa_find_line_column((const GLubyte *) source,
- (const GLubyte *) source + pos,
- &line, &col);
- printf("Error on line %d, col %d: %s\n", line, col, s);
- }
-#endif
- return GL_FALSE;
- }
-
- /* Syntax is okay - translate it to internal representation. */
- if (!compile_binary(prod, unit, version, type, infolog, builtin,
- &builtin[SLANG_BUILTIN_TOTAL - 1],
- shader)) {
- free(prod);
- return GL_FALSE;
- }
- free(prod);
- return GL_TRUE;
-}
-
-static const unsigned char slang_core_gc[] = {
-#include "library/slang_core_gc.h"
-};
-
-static const unsigned char slang_120_core_gc[] = {
-#include "library/slang_120_core_gc.h"
-};
-
-static const unsigned char slang_120_fragment_gc[] = {
-#include "library/slang_builtin_120_fragment_gc.h"
-};
-
-static const unsigned char slang_common_builtin_gc[] = {
-#include "library/slang_common_builtin_gc.h"
-};
-
-static const unsigned char slang_fragment_builtin_gc[] = {
-#include "library/slang_fragment_builtin_gc.h"
-};
-
-static const unsigned char slang_vertex_builtin_gc[] = {
-#include "library/slang_vertex_builtin_gc.h"
-};
-
-static const unsigned char slang_geometry_builtin_gc[] = {
-#include "library/slang_geometry_builtin_gc.h"
-};
-
-static GLboolean
-compile_object(const char *source,
- slang_code_object *object,
- slang_unit_type type,
- slang_info_log *infolog,
- struct gl_shader *shader,
- struct gl_sl_pragmas *pragmas)
-{
- slang_code_unit *builtins = NULL;
- GLuint base_version = 110;
- unsigned int shader_type;
- unsigned int parsing_builtin;
-
- /* set shader type - the syntax is slightly different for different shaders */
- if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_FRAGMENT_BUILTIN) {
- shader_type = 1;
- } else {
- shader_type = 2;
- }
-
- /* enable language extensions */
- parsing_builtin = 1;
-
- /* if parsing user-specified shader, load built-in library */
- if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER ||
- type == SLANG_UNIT_GEOMETRY_SHADER) {
- /* compile core functionality first */
- if (!compile_binary(slang_core_gc,
- &object->builtin[SLANG_BUILTIN_CORE],
- base_version,
- SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
- NULL, NULL, NULL))
- return GL_FALSE;
-
-#if FEATURE_ARB_shading_language_120
- if (!compile_binary(slang_120_core_gc,
- &object->builtin[SLANG_BUILTIN_120_CORE],
- 120,
- SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
- NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL))
- return GL_FALSE;
-#endif
-
- /* compile common functions and variables, link to core */
- if (!compile_binary(slang_common_builtin_gc,
- &object->builtin[SLANG_BUILTIN_COMMON],
-#if FEATURE_ARB_shading_language_120
- 120,
-#else
- base_version,
-#endif
- SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
-#if FEATURE_ARB_shading_language_120
- &object->builtin[SLANG_BUILTIN_120_CORE],
-#else
- &object->builtin[SLANG_BUILTIN_CORE],
-#endif
- NULL))
- return GL_FALSE;
-
- /* compile target-specific functions and variables, link to common */
- if (type == SLANG_UNIT_FRAGMENT_SHADER) {
- if (!compile_binary(slang_fragment_builtin_gc,
- &object->builtin[SLANG_BUILTIN_TARGET],
- base_version,
- SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_COMMON], NULL))
- return GL_FALSE;
-#if FEATURE_ARB_shading_language_120
- if (!compile_binary(slang_120_fragment_gc,
- &object->builtin[SLANG_BUILTIN_TARGET],
- 120,
- SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_COMMON], NULL))
- return GL_FALSE;
-#endif
- }
- else if (type == SLANG_UNIT_VERTEX_SHADER) {
- if (!compile_binary(slang_vertex_builtin_gc,
- &object->builtin[SLANG_BUILTIN_TARGET],
- base_version,
- SLANG_UNIT_VERTEX_BUILTIN, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_COMMON], NULL))
- return GL_FALSE;
- }
-#if FEATURE_ARB_geometry_shader4
- else if (type == SLANG_UNIT_GEOMETRY_SHADER) {
- if (!compile_binary(slang_geometry_builtin_gc,
- &object->builtin[SLANG_BUILTIN_TARGET],
- base_version,
- SLANG_UNIT_GEOMETRY_BUILTIN, infolog, NULL,
- &object->builtin[SLANG_BUILTIN_COMMON], NULL))
- return GL_FALSE;
- }
-#endif
-
- /* disable language extensions */
- parsing_builtin = 0;
-
- builtins = object->builtin;
- }
-
- /* compile the actual shader - pass-in built-in library for external shader */
- return compile_with_grammar(source,
- &object->unit,
- type,
- infolog,
- builtins,
- shader,
- pragmas,
- shader_type,
- parsing_builtin);
-}
-
-
-GLboolean
-_slang_compile(GLcontext *ctx, struct gl_shader *shader)
-{
- GLboolean success;
- slang_info_log info_log;
- slang_code_object obj;
- slang_unit_type type;
- GLenum progTarget;
-
- if (shader->Type == GL_VERTEX_SHADER) {
- type = SLANG_UNIT_VERTEX_SHADER;
- }
- else if (shader->Type == GL_FRAGMENT_SHADER) {
- type = SLANG_UNIT_FRAGMENT_SHADER;
- } else {
- assert(shader->Type == GL_GEOMETRY_SHADER_ARB);
- type = SLANG_UNIT_GEOMETRY_SHADER;
- }
-
- if (!shader->Source)
- return GL_FALSE;
-
- ctx->Shader.MemPool = _slang_new_mempool(1024*1024);
-
- shader->Main = GL_FALSE;
-
- /* free the shader's old instructions, etc */
- _mesa_reference_program(ctx, &shader->Program, NULL);
-
- /* allocate new GPU program, parameter lists, etc. */
- if (shader->Type == GL_VERTEX_SHADER)
- progTarget = GL_VERTEX_PROGRAM_ARB;
- else if (shader->Type == GL_FRAGMENT_SHADER)
- progTarget = GL_FRAGMENT_PROGRAM_ARB;
- else
- progTarget = MESA_GEOMETRY_PROGRAM;
- shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
- shader->Program->Parameters = _mesa_new_parameter_list();
- shader->Program->Varying = _mesa_new_parameter_list();
- shader->Program->Attributes = _mesa_new_parameter_list();
-
- slang_info_log_construct(&info_log);
- _slang_code_object_ctr(&obj);
-
- success = compile_object(shader->Source,
- &obj,
- type,
- &info_log,
- shader,
- &shader->Pragmas);
-
- /* free shader's prev info log */
- if (shader->InfoLog) {
- free(shader->InfoLog);
- shader->InfoLog = NULL;
- }
-
- if (info_log.text) {
- /* copy info-log string to shader object */
- shader->InfoLog = _mesa_strdup(info_log.text);
- }
-
- if (info_log.error_flag) {
- success = GL_FALSE;
- }
-
- slang_info_log_destruct(&info_log);
- _slang_code_object_dtr(&obj);
-
- _slang_delete_mempool((slang_mempool *) ctx->Shader.MemPool);
- ctx->Shader.MemPool = NULL;
-
- /* remove any reads of output registers */
-#if 0
- printf("Pre-remove output reads:\n");
- _mesa_print_program(shader->Program);
-#endif
- _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT);
- if (shader->Type == GL_VERTEX_SHADER) {
- /* and remove writes to varying vars in vertex programs */
- _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING);
- }
-#if 0
- printf("Post-remove output reads:\n");
- _mesa_print_program(shader->Program);
-#endif
-
- shader->CompileStatus = success;
-
- if (success) {
- if (shader->Pragmas.Optimize &&
- (ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
- _mesa_optimize_program(ctx, shader->Program);
- }
- if ((ctx->Shader.Flags & GLSL_NOP_VERT) &&
- shader->Program->Target == GL_VERTEX_PROGRAM_ARB) {
- _mesa_nop_vertex_program(ctx,
- (struct gl_vertex_program *) shader->Program);
- }
- if ((ctx->Shader.Flags & GLSL_NOP_FRAG) &&
- shader->Program->Target == GL_FRAGMENT_PROGRAM_ARB) {
- _mesa_nop_fragment_program(ctx,
- (struct gl_fragment_program *) shader->Program);
- }
- }
-
- if (ctx->Shader.Flags & GLSL_LOG) {
- _mesa_write_shader_to_file(shader);
- }
-
- return success;
-}
-
diff --git a/src/mesa/slang/slang_compile.h b/src/mesa/slang/slang_compile.h
deleted file mode 100644
index 6061f878e75..00000000000
--- a/src/mesa/slang/slang_compile.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-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.
- */
-
-#if !defined SLANG_COMPILE_H
-#define SLANG_COMPILE_H
-
-#include "main/glheader.h"
-#include "main/mtypes.h"
-#include "slang_compile_function.h"
-#include "slang_compile_struct.h"
-#include "slang_compile_variable.h"
-#include "slang_utility.h"
-
-struct slang_code_object_;
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-typedef struct slang_name_space_
-{
- struct slang_function_scope_ *funcs;
- struct slang_struct_scope_ *structs;
- struct slang_variable_scope_ *vars;
-} slang_name_space;
-
-typedef enum slang_unit_type_
-{
- SLANG_UNIT_FRAGMENT_SHADER,
- SLANG_UNIT_VERTEX_SHADER,
- SLANG_UNIT_GEOMETRY_SHADER,
- SLANG_UNIT_FRAGMENT_BUILTIN,
- SLANG_UNIT_VERTEX_BUILTIN,
- SLANG_UNIT_GEOMETRY_BUILTIN
-} slang_unit_type;
-
-
-typedef struct slang_code_unit_
-{
- slang_variable_scope vars;
- slang_function_scope funs;
- slang_struct_scope structs;
- slang_unit_type type;
- struct slang_code_object_ *object;
-} slang_code_unit;
-
-
-extern GLvoid
-_slang_code_unit_ctr (slang_code_unit *, struct slang_code_object_ *);
-
-extern GLvoid
-_slang_code_unit_dtr (slang_code_unit *);
-
-#define SLANG_BUILTIN_CORE 0
-#define SLANG_BUILTIN_120_CORE 1
-#define SLANG_BUILTIN_COMMON 2
-#define SLANG_BUILTIN_TARGET 3
-
-#define SLANG_BUILTIN_TOTAL 4
-
-typedef struct slang_code_object_
-{
- slang_code_unit builtin[SLANG_BUILTIN_TOTAL];
- slang_code_unit unit;
- slang_atom_pool atompool;
-} slang_code_object;
-
-extern GLvoid
-_slang_code_object_ctr (slang_code_object *);
-
-extern GLvoid
-_slang_code_object_dtr (slang_code_object *);
-
-extern GLboolean
-_slang_compile (GLcontext *ctx, struct gl_shader *shader);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/mesa/slang/slang_compile_function.c b/src/mesa/slang/slang_compile_function.c
deleted file mode 100644
index 4dd885176d4..00000000000
--- a/src/mesa/slang/slang_compile_function.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-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 slang_compile_function.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_mem.h"
-
-
-int
-slang_function_construct(slang_function * func)
-{
- func->kind = SLANG_FUNC_ORDINARY;
- if (!slang_variable_construct(&func->header))
- return 0;
-
- func->parameters = (slang_variable_scope *)
- _slang_alloc(sizeof(slang_variable_scope));
- if (func->parameters == NULL) {
- slang_variable_destruct(&func->header);
- return 0;
- }
-
- _slang_variable_scope_ctr(func->parameters);
- func->param_count = 0;
- func->body = NULL;
- return 1;
-}
-
-void
-slang_function_destruct(slang_function * func)
-{
- slang_variable_destruct(&func->header);
- slang_variable_scope_destruct(func->parameters);
- _slang_free(func->parameters);
- if (func->body != NULL) {
- slang_operation_destruct(func->body);
- _slang_free(func->body);
- }
-}
-
-
-slang_function *
-slang_function_new(slang_function_kind kind)
-{
- slang_function *fun = (slang_function *)
- _slang_alloc(sizeof(slang_function));
- if (fun) {
- slang_function_construct(fun);
- fun->kind = kind;
- }
- return fun;
-}
-
-
-/*
- * slang_function_scope
- */
-
-GLvoid
-_slang_function_scope_ctr(slang_function_scope * self)
-{
- self->functions = NULL;
- self->num_functions = 0;
- self->outer_scope = NULL;
-}
-
-void
-slang_function_scope_destruct(slang_function_scope * scope)
-{
- unsigned int i;
-
- for (i = 0; i < scope->num_functions; i++)
- slang_function_destruct(scope->functions + i);
- _slang_free(scope->functions);
-}
-
-
-/**
- * Does this function have a non-void return value?
- */
-GLboolean
-_slang_function_has_return_value(const slang_function *fun)
-{
- return fun->header.type.specifier.type != SLANG_SPEC_VOID;
-}
-
-
-/**
- * Search a list of functions for a particular function by name.
- * \param funcs the list of functions to search
- * \param a_name the name to search for
- * \param all_scopes if non-zero, search containing scopes too.
- * \return pointer to found function, or NULL.
- */
-int
-slang_function_scope_find_by_name(slang_function_scope * funcs,
- slang_atom a_name, int all_scopes)
-{
- unsigned int i;
-
- for (i = 0; i < funcs->num_functions; i++)
- if (a_name == funcs->functions[i].header.a_name)
- return 1;
- if (all_scopes && funcs->outer_scope != NULL)
- return slang_function_scope_find_by_name(funcs->outer_scope, a_name, 1);
- return 0;
-}
-
-
-/**
- * Search a list of functions for a particular function (for implementing
- * function calls. Matching is done by first comparing the function's name,
- * then the function's parameter list.
- *
- * \param funcs the list of functions to search
- * \param fun the function to search for
- * \param all_scopes if non-zero, search containing scopes too.
- * \return pointer to found function, or NULL.
- */
-slang_function *
-slang_function_scope_find(slang_function_scope * funcs, slang_function * fun,
- int all_scopes)
-{
- unsigned int i;
-
- for (i = 0; i < funcs->num_functions; i++) {
- slang_function *f = &funcs->functions[i];
- const GLuint haveRetValue = 0;
-#if 0
- = (f->header.type.specifier.type != SLANG_SPEC_VOID);
-#endif
- unsigned int j;
-
- /*
- printf("Compare name %s to %s (ret %u, %d, %d)\n",
- (char *) fun->header.a_name, (char *) f->header.a_name,
- haveRetValue,
- fun->param_count, f->param_count);
- */
-
- if (fun->header.a_name != f->header.a_name)
- continue;
- if (fun->param_count != f->param_count)
- continue;
- for (j = haveRetValue; j < fun->param_count; j++) {
- if (!slang_type_specifier_equal
- (&fun->parameters->variables[j]->type.specifier,
- &f->parameters->variables[j]->type.specifier))
- break;
- }
- if (j == fun->param_count) {
- /*
- printf("Found match\n");
- */
- return f;
- }
- }
- /*
- printf("Not found\n");
- */
- if (all_scopes && funcs->outer_scope != NULL)
- return slang_function_scope_find(funcs->outer_scope, fun, 1);
- return NULL;
-}
-
-
-/**
- * Lookup a function according to name and parameter count/types.
- */
-slang_function *
-_slang_function_locate(const slang_function_scope * funcs, slang_atom a_name,
- slang_operation * args, GLuint num_args,
- const slang_name_space * space, slang_atom_pool * atoms,
- slang_info_log *log, GLboolean *error)
-{
- slang_typeinfo arg_ti[100];
- GLuint i;
-
- *error = GL_FALSE;
-
- /* determine type of each argument */
- assert(num_args < 100);
- for (i = 0; i < num_args; i++) {
- if (!slang_typeinfo_construct(&arg_ti[i]))
- return NULL;
- if (!_slang_typeof_operation(&args[i], space, &arg_ti[i], atoms, log)) {
- return NULL;
- }
- }
-
- /* loop over function scopes */
- while (funcs) {
-
- /* look for function with matching name and argument/param types */
- for (i = 0; i < funcs->num_functions; i++) {
- slang_function *f = &funcs->functions[i];
- const GLuint haveRetValue = _slang_function_has_return_value(f);
- GLuint j;
-
- if (a_name != f->header.a_name)
- continue;
- if (f->param_count - haveRetValue != num_args)
- continue;
-
- /* compare parameter / argument types */
- for (j = 0; j < num_args; j++) {
- if (!slang_type_specifier_compatible(&arg_ti[j].spec,
- &f->parameters->variables[j]->type.specifier)) {
- /* param/arg types don't match */
- break;
- }
-
- /* "out" and "inout" formal parameter requires the actual
- * argument to be an l-value.
- */
- if (!arg_ti[j].can_be_referenced &&
- (f->parameters->variables[j]->type.qualifier == SLANG_QUAL_OUT ||
- f->parameters->variables[j]->type.qualifier == SLANG_QUAL_INOUT)) {
- /* param is not an lvalue! */
- *error = GL_TRUE;
- return NULL;
- }
- }
-
- if (j == num_args) {
- /* name and args match! */
- return f;
- }
- }
-
- funcs = funcs->outer_scope;
- }
-
- return NULL;
-}
diff --git a/src/mesa/slang/slang_compile_function.h b/src/mesa/slang/slang_compile_function.h
deleted file mode 100644
index 0eced3ca1a1..00000000000
--- a/src/mesa/slang/slang_compile_function.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 2005-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 SLANG_COMPILE_FUNCTION_H
-#define SLANG_COMPILE_FUNCTION_H
-
-#include "main/glheader.h"
-#include "slang_compile_operation.h"
-#include "slang_compile_variable.h"
-#include "slang_log.h"
-#include "slang_utility.h"
-
-struct slang_name_space_;
-struct slang_operation_;
-
-/**
- * Types of functions.
- */
-typedef enum slang_function_kind_
-{
- SLANG_FUNC_ORDINARY,
- SLANG_FUNC_CONSTRUCTOR,
- SLANG_FUNC_OPERATOR
-} slang_function_kind;
-
-
-/**
- * Description of a compiled shader function.
- */
-typedef struct slang_function_
-{
- slang_function_kind kind;
- slang_variable header; /**< The function's name and return type */
- slang_variable_scope *parameters; /**< formal parameters AND local vars */
- unsigned int param_count; /**< number of formal params (no locals) */
- slang_operation *body; /**< The instruction tree */
-} slang_function;
-
-extern int slang_function_construct(slang_function *);
-extern void slang_function_destruct(slang_function *);
-extern slang_function *slang_function_new(slang_function_kind kind);
-
-extern GLboolean
-_slang_function_has_return_value(const slang_function *fun);
-
-
-/**
- * Basically, a list of compiled functions.
- */
-typedef struct slang_function_scope_
-{
- slang_function *functions;
- GLuint num_functions;
- struct slang_function_scope_ *outer_scope;
-} slang_function_scope;
-
-
-extern GLvoid
-_slang_function_scope_ctr(slang_function_scope *);
-
-extern void
-slang_function_scope_destruct(slang_function_scope *);
-
-extern int
-slang_function_scope_find_by_name(slang_function_scope *, slang_atom, int);
-
-extern slang_function *
-slang_function_scope_find(slang_function_scope *, slang_function *, int);
-
-extern struct slang_function_ *
-_slang_function_locate(const struct slang_function_scope_ *funcs,
- slang_atom name, struct slang_operation_ *params,
- GLuint num_params,
- const struct slang_name_space_ *space,
- slang_atom_pool *atoms, slang_info_log *log,
- GLboolean *error);
-
-
-#endif /* SLANG_COMPILE_FUNCTION_H */
diff --git a/src/mesa/slang/slang_compile_operation.c b/src/mesa/slang/slang_compile_operation.c
deleted file mode 100644
index 5441d60df59..00000000000
--- a/src/mesa/slang/slang_compile_operation.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 2005-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 slang_compile_operation.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_mem.h"
-
-
-/**
- * Init a slang_operation object
- */
-GLboolean
-slang_operation_construct(slang_operation * oper)
-{
- oper->type = SLANG_OPER_NONE;
- oper->children = NULL;
- oper->num_children = 0;
- oper->literal[0] = 0.0;
- oper->literal_size = 1;
- oper->array_constructor = GL_FALSE;
- oper->a_id = SLANG_ATOM_NULL;
- oper->a_obj = SLANG_ATOM_NULL;
- oper->locals = _slang_variable_scope_new(NULL);
- if (oper->locals == NULL)
- return GL_FALSE;
- _slang_variable_scope_ctr(oper->locals);
- oper->fun = NULL;
- oper->var = NULL;
- oper->label = NULL;
- return GL_TRUE;
-}
-
-void
-slang_operation_destruct(slang_operation * oper)
-{
- GLuint i;
-
- for (i = 0; i < oper->num_children; i++)
- slang_operation_destruct(oper->children + i);
- _slang_free(oper->children);
- slang_variable_scope_destruct(oper->locals);
- _slang_free(oper->locals);
- oper->children = NULL;
- oper->num_children = 0;
- oper->locals = NULL;
-}
-
-
-/**
- * Recursively traverse 'oper', replacing occurances of 'oldScope' with
- * 'newScope' in the oper->locals->outer_scope field.
- */
-void
-slang_replace_scope(slang_operation *oper,
- slang_variable_scope *oldScope,
- slang_variable_scope *newScope)
-{
- GLuint i;
-
- if (oper->locals != newScope &&
- oper->locals->outer_scope == oldScope) {
- /* found. replace old w/ new */
- oper->locals->outer_scope = newScope;
- }
-
- if (oper->type == SLANG_OPER_VARIABLE_DECL) {
- /* search/replace in the initializer */
- slang_variable *var;
- var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
- if (var && var->initializer) {
- slang_replace_scope(var->initializer, oldScope, newScope);
- }
- }
-
- /* search/replace in children */
- for (i = 0; i < oper->num_children; i++) {
- slang_replace_scope(&oper->children[i], oldScope, newScope);
- }
-}
-
-
-/**
- * Recursively copy a slang_operation node.
- * \param x copy target
- * \param y copy source
- * \return GL_TRUE for success, GL_FALSE if failure
- */
-GLboolean
-slang_operation_copy(slang_operation * x, const slang_operation * y)
-{
- slang_operation z;
- GLuint i;
-
- if (!slang_operation_construct(&z))
- return GL_FALSE;
- z.type = y->type;
- if (y->num_children > 0) {
- z.children = (slang_operation *)
- _slang_alloc(y->num_children * sizeof(slang_operation));
- if (z.children == NULL) {
- slang_operation_destruct(&z);
- return GL_FALSE;
- }
- }
- for (z.num_children = 0; z.num_children < y->num_children;
- z.num_children++) {
- if (!slang_operation_construct(&z.children[z.num_children])) {
- slang_operation_destruct(&z);
- return GL_FALSE;
- }
- }
- for (i = 0; i < z.num_children; i++) {
- if (!slang_operation_copy(&z.children[i], &y->children[i])) {
- slang_operation_destruct(&z);
- return GL_FALSE;
- }
- }
- z.literal[0] = y->literal[0];
- z.literal[1] = y->literal[1];
- z.literal[2] = y->literal[2];
- z.literal[3] = y->literal[3];
- z.literal_size = y->literal_size;
- assert(y->literal_size >= 1);
- assert(y->literal_size <= 4);
- z.a_id = y->a_id;
- if (y->locals) {
- if (!slang_variable_scope_copy(z.locals, y->locals)) {
- slang_operation_destruct(&z);
- return GL_FALSE;
- }
- }
-
- /* update scoping for children */
- for (i = 0; i < y->num_children; i++) {
- if (y->children[i].locals &&
- y->children[i].locals->outer_scope == y->locals) {
- z.children[i].locals->outer_scope = z.locals;
- }
- }
-
-#if 0
- z.var = y->var;
- z.fun = y->fun;
-#endif
- slang_operation_destruct(x);
- *x = z;
-
- /* If this operation declares a new scope, we need to make sure
- * all children point to it, not the original operation's scope!
- */
- if (x->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
- x->type == SLANG_OPER_WHILE ||
- x->type == SLANG_OPER_FOR) {
- slang_replace_scope(x, y->locals, x->locals);
- }
-
- return GL_TRUE;
-}
-
-
-slang_operation *
-slang_operation_new(GLuint count)
-{
- slang_operation *ops
- = (slang_operation *) _slang_alloc(count * sizeof(slang_operation));
- assert(count > 0);
- if (ops) {
- GLuint i;
- for (i = 0; i < count; i++)
- slang_operation_construct(ops + i);
- }
- return ops;
-}
-
-
-/**
- * Delete operation and all children
- */
-void
-slang_operation_delete(slang_operation *oper)
-{
- slang_operation_destruct(oper);
- _slang_free(oper);
-}
-
-
-void
-slang_operation_free_children(slang_operation *oper)
-{
- GLuint i;
- for (i = 0; i < slang_oper_num_children(oper); i++) {
- slang_operation *child = slang_oper_child(oper, i);
- slang_operation_destruct(child);
- }
- _slang_free(oper->children);
- oper->children = NULL;
- oper->num_children = 0;
-}
-
-
-slang_operation *
-slang_operation_grow(GLuint *numChildren, slang_operation **children)
-{
- slang_operation *ops;
-
- ops = (slang_operation *)
- _slang_realloc(*children,
- *numChildren * sizeof(slang_operation),
- (*numChildren + 1) * sizeof(slang_operation));
- if (ops) {
- slang_operation *newOp = ops + *numChildren;
- if (!slang_operation_construct(newOp)) {
- _slang_free(ops);
- *children = NULL;
- return NULL;
- }
- *children = ops;
- (*numChildren)++;
- return newOp;
- }
- return NULL;
-}
-
-/**
- * Insert a new slang_operation into an array.
- * \param numElements pointer to current array size (in/out)
- * \param array address of the array (in/out)
- * \param pos position to insert new element
- * \return pointer to the new operation/element
- */
-slang_operation *
-slang_operation_insert(GLuint *numElements, slang_operation **array,
- GLuint pos)
-{
- slang_operation *ops;
-
- assert(pos <= *numElements);
-
- ops = (slang_operation *)
- _slang_alloc((*numElements + 1) * sizeof(slang_operation));
- if (ops) {
- slang_operation *newOp;
- newOp = ops + pos;
- if (pos > 0)
- memcpy(ops, *array, pos * sizeof(slang_operation));
- if (pos < *numElements)
- memcpy(newOp + 1, (*array) + pos,
- (*numElements - pos) * sizeof(slang_operation));
-
- if (!slang_operation_construct(newOp)) {
- _slang_free(ops);
- *numElements = 0;
- *array = NULL;
- return NULL;
- }
- if (*array)
- _slang_free(*array);
- *array = ops;
- (*numElements)++;
- return newOp;
- }
- return NULL;
-}
-
-
-/**
- * Add/insert new child into given node at given position.
- * \return pointer to the new child node
- */
-slang_operation *
-slang_operation_insert_child(slang_operation *oper, GLuint pos)
-{
- slang_operation *newOp;
-
- newOp = slang_operation_insert(&oper->num_children,
- &oper->children,
- pos);
- if (newOp) {
- newOp->locals->outer_scope = oper->locals;
- }
-
- return newOp;
-}
-
-
-void
-_slang_operation_swap(slang_operation *oper0, slang_operation *oper1)
-{
- slang_operation tmp = *oper0;
- *oper0 = *oper1;
- *oper1 = tmp;
-}
-
-
-void
-slang_operation_add_children(slang_operation *oper, GLuint num_children)
-{
- GLuint i;
- assert(oper->num_children == 0);
- assert(oper->children == NULL);
- oper->num_children = num_children;
- oper->children = slang_operation_new(num_children);
- for (i = 0; i < num_children; i++) {
- oper->children[i].locals = _slang_variable_scope_new(oper->locals);
- }
-}
-
diff --git a/src/mesa/slang/slang_compile_operation.h b/src/mesa/slang/slang_compile_operation.h
deleted file mode 100644
index b8c5f214cf0..00000000000
--- a/src/mesa/slang/slang_compile_operation.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 2005-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 SLANG_COMPILE_OPERATION_H
-#define SLANG_COMPILE_OPERATION_H
-
-
-#include "main/glheader.h"
-#include "slang_compile_variable.h"
-#include "slang_utility.h"
-
-/**
- * Types of slang operations.
- * These are the types of the AST (abstract syntax tree) nodes.
- * [foo] indicates a sub-tree or reference to another type of node
- */
-typedef enum slang_operation_type_
-{
- SLANG_OPER_NONE,
- SLANG_OPER_BLOCK_NO_NEW_SCOPE, /* "{" sequence "}" */
- SLANG_OPER_BLOCK_NEW_SCOPE, /* "{" sequence "}" */
- SLANG_OPER_VARIABLE_DECL, /* [type] [var] or [var] = [expr] */
- SLANG_OPER_ASM,
- SLANG_OPER_BREAK, /* "break" statement */
- SLANG_OPER_CONTINUE, /* "continue" statement */
- SLANG_OPER_DISCARD, /* "discard" (kill fragment) statement */
- SLANG_OPER_RETURN, /* "return" [expr] */
- SLANG_OPER_RETURN_INLINED, /* "return" [expr] from inlined function */
- SLANG_OPER_LABEL, /* a jump target */
- SLANG_OPER_EXPRESSION, /* [expr] */
- SLANG_OPER_IF, /* "if" [0] then [1] else [2] */
- SLANG_OPER_WHILE, /* "while" [cond] [body] */
- SLANG_OPER_DO, /* "do" [body] "while" [cond] */
- SLANG_OPER_FOR, /* "for" [init] [while] [incr] [body] */
- SLANG_OPER_VOID, /* nop */
- SLANG_OPER_LITERAL_BOOL, /* "true" or "false" */
- SLANG_OPER_LITERAL_INT, /* integer literal */
- SLANG_OPER_LITERAL_FLOAT, /* float literal */
- SLANG_OPER_IDENTIFIER, /* var name, func name, etc */
- SLANG_OPER_SEQUENCE, /* [expr] "," [expr] "," etc */
- SLANG_OPER_ASSIGN, /* [var] "=" [expr] */
- SLANG_OPER_ADDASSIGN, /* [var] "+=" [expr] */
- SLANG_OPER_SUBASSIGN, /* [var] "-=" [expr] */
- SLANG_OPER_MULASSIGN, /* [var] "*=" [expr] */
- SLANG_OPER_DIVASSIGN, /* [var] "/=" [expr] */
- /*SLANG_OPER_MODASSIGN, */
- /*SLANG_OPER_LSHASSIGN, */
- /*SLANG_OPER_RSHASSIGN, */
- /*SLANG_OPER_ORASSIGN, */
- /*SLANG_OPER_XORASSIGN, */
- /*SLANG_OPER_ANDASSIGN, */
- SLANG_OPER_SELECT, /* [expr] "?" [expr] ":" [expr] */
- SLANG_OPER_LOGICALOR, /* [expr] "||" [expr] */
- SLANG_OPER_LOGICALXOR, /* [expr] "^^" [expr] */
- SLANG_OPER_LOGICALAND, /* [expr] "&&" [expr] */
- /*SLANG_OPER_BITOR, */
- /*SLANG_OPER_BITXOR, */
- /*SLANG_OPER_BITAND, */
- SLANG_OPER_EQUAL, /* [expr] "==" [expr] */
- SLANG_OPER_NOTEQUAL, /* [expr] "!=" [expr] */
- SLANG_OPER_LESS, /* [expr] "<" [expr] */
- SLANG_OPER_GREATER, /* [expr] ">" [expr] */
- SLANG_OPER_LESSEQUAL, /* [expr] "<=" [expr] */
- SLANG_OPER_GREATEREQUAL, /* [expr] ">=" [expr] */
- /*SLANG_OPER_LSHIFT, */
- /*SLANG_OPER_RSHIFT, */
- SLANG_OPER_ADD, /* [expr] "+" [expr] */
- SLANG_OPER_SUBTRACT, /* [expr] "-" [expr] */
- SLANG_OPER_MULTIPLY, /* [expr] "*" [expr] */
- SLANG_OPER_DIVIDE, /* [expr] "/" [expr] */
- /*SLANG_OPER_MODULUS, */
- SLANG_OPER_PREINCREMENT, /* "++" [var] */
- SLANG_OPER_PREDECREMENT, /* "--" [var] */
- SLANG_OPER_PLUS, /* "-" [expr] */
- SLANG_OPER_MINUS, /* "+" [expr] */
- /*SLANG_OPER_COMPLEMENT, */
- SLANG_OPER_NOT, /* "!" [expr] */
- SLANG_OPER_SUBSCRIPT, /* [expr] "[" [expr] "]" */
- SLANG_OPER_CALL, /* [func name] [param] [param] [...] */
- SLANG_OPER_NON_INLINED_CALL, /* a real function call */
- SLANG_OPER_METHOD, /* method call, such as v.length() */
- SLANG_OPER_FIELD, /* i.e.: ".next" or ".xzy" or ".xxx" etc */
- SLANG_OPER_POSTINCREMENT, /* [var] "++" */
- SLANG_OPER_POSTDECREMENT /* [var] "--" */
-} slang_operation_type;
-
-
-/**
- * A slang_operation is basically a compiled instruction (such as assignment,
- * a while-loop, a conditional, a multiply, a function call, etc).
- * The AST (abstract syntax tree) is built from these nodes.
- * NOTE: This structure could have been implemented as a union of simpler
- * structs which would correspond to the operation types above.
- */
-typedef struct slang_operation_
-{
- slang_operation_type type;
- struct slang_operation_ *children;
- GLuint num_children;
- GLfloat literal[4]; /**< Used for float, int and bool values */
- GLuint literal_size; /**< 1, 2, 3, or 4 */
- slang_atom a_id; /**< type: asm, identifier, call, field */
- slang_atom a_obj; /**< object in a method call */
- slang_variable_scope *locals; /**< local vars for scope */
- struct slang_function_ *fun; /**< If type == SLANG_OPER_CALL */
- struct slang_variable_ *var; /**< If type == slang_oper_identier */
- struct slang_label_ *label; /**< If type == SLANG_OPER_LABEL */
- /** If type==SLANG_OPER_CALL and we're calling an array constructor,
- * for which there's no real function, we need to have a flag to
- * indicate such. num_children indicates number of elements.
- */
- GLboolean array_constructor;
-} slang_operation;
-
-
-extern GLboolean
-slang_operation_construct(slang_operation *);
-
-extern void
-slang_operation_destruct(slang_operation *);
-
-extern void
-slang_replace_scope(slang_operation *oper,
- slang_variable_scope *oldScope,
- slang_variable_scope *newScope);
-
-extern GLboolean
-slang_operation_copy(slang_operation *, const slang_operation *);
-
-extern slang_operation *
-slang_operation_new(GLuint count);
-
-extern void
-slang_operation_delete(slang_operation *oper);
-
-extern void
-slang_operation_free_children(slang_operation *oper);
-
-extern slang_operation *
-slang_operation_grow(GLuint *numChildren, slang_operation **children);
-
-extern slang_operation *
-slang_operation_insert(GLuint *numChildren, slang_operation **children,
- GLuint pos);
-
-extern slang_operation *
-slang_operation_insert_child(slang_operation *oper, GLuint pos);
-
-extern void
-_slang_operation_swap(slang_operation *oper0, slang_operation *oper1);
-
-
-extern void
-slang_operation_add_children(slang_operation *oper, GLuint num_children);
-
-
-/** Return number of children of given node */
-static INLINE GLuint
-slang_oper_num_children(const slang_operation *oper)
-{
- return oper->num_children;
-}
-
-/** Return child of given operation node */
-static INLINE slang_operation *
-slang_oper_child(slang_operation *oper, GLuint child)
-{
- assert(child < oper->num_children);
- return &oper->children[child];
-}
-
-
-/** Return child of given operation node, const version */
-static INLINE const slang_operation *
-slang_oper_child_const(const slang_operation *oper, GLuint child)
-{
- assert(child < oper->num_children);
- return &oper->children[child];
-}
-
-
-/** Init oper to a boolean literal. */
-static INLINE void
-slang_operation_literal_bool(slang_operation *oper, GLboolean value)
-{
- oper->type = SLANG_OPER_LITERAL_BOOL;
- oper->literal[0] =
- oper->literal[1] =
- oper->literal[2] =
- oper->literal[3] = (float) value;
- oper->literal_size = 1;
-}
-
-
-/** Init oper to an int literal. */
-static INLINE void
-slang_operation_literal_int(slang_operation *oper, GLint value)
-{
- oper->type = SLANG_OPER_LITERAL_INT;
- oper->literal[0] =
- oper->literal[1] =
- oper->literal[2] =
- oper->literal[3] = (float) value;
- oper->literal_size = 1;
-}
-
-
-#endif /* SLANG_COMPILE_OPERATION_H */
diff --git a/src/mesa/slang/slang_compile_struct.c b/src/mesa/slang/slang_compile_struct.c
deleted file mode 100644
index e6c38730d7d..00000000000
--- a/src/mesa/slang/slang_compile_struct.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-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 slang_compile_struct.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_mem.h"
-#include "slang_compile.h"
-
-
-GLvoid
-_slang_struct_scope_ctr(slang_struct_scope * self)
-{
- self->structs = NULL;
- self->num_structs = 0;
- self->outer_scope = NULL;
-}
-
-void
-slang_struct_scope_destruct(slang_struct_scope * scope)
-{
- GLuint i;
-
- for (i = 0; i < scope->num_structs; i++)
- slang_struct_destruct(scope->structs + i);
- _slang_free(scope->structs);
- /* do not free scope->outer_scope */
-}
-
-int
-slang_struct_scope_copy(slang_struct_scope * x, const slang_struct_scope * y)
-{
- slang_struct_scope z;
- GLuint i;
-
- _slang_struct_scope_ctr(&z);
- z.structs = (slang_struct *)
- _slang_alloc(y->num_structs * sizeof(slang_struct));
- if (z.structs == NULL) {
- slang_struct_scope_destruct(&z);
- return 0;
- }
- for (z.num_structs = 0; z.num_structs < y->num_structs; z.num_structs++)
- if (!slang_struct_construct(&z.structs[z.num_structs])) {
- slang_struct_scope_destruct(&z);
- return 0;
- }
- for (i = 0; i < z.num_structs; i++)
- if (!slang_struct_copy(&z.structs[i], &y->structs[i])) {
- slang_struct_scope_destruct(&z);
- return 0;
- }
- z.outer_scope = y->outer_scope;
- slang_struct_scope_destruct(x);
- *x = z;
- return 1;
-}
-
-slang_struct *
-slang_struct_scope_find(slang_struct_scope * stru, slang_atom a_name,
- int all_scopes)
-{
- GLuint i;
-
- for (i = 0; i < stru->num_structs; i++)
- if (a_name == stru->structs[i].a_name)
- return &stru->structs[i];
- if (all_scopes && stru->outer_scope != NULL)
- return slang_struct_scope_find(stru->outer_scope, a_name, 1);
- return NULL;
-}
-
-/* slang_struct */
-
-int
-slang_struct_construct(slang_struct * stru)
-{
- stru->a_name = SLANG_ATOM_NULL;
- stru->fields = (slang_variable_scope *)
- _slang_alloc(sizeof(slang_variable_scope));
- if (stru->fields == NULL)
- return 0;
- _slang_variable_scope_ctr(stru->fields);
-
- stru->structs =
- (slang_struct_scope *) _slang_alloc(sizeof(slang_struct_scope));
- if (stru->structs == NULL) {
- slang_variable_scope_destruct(stru->fields);
- _slang_free(stru->fields);
- return 0;
- }
- _slang_struct_scope_ctr(stru->structs);
- stru->constructor = NULL;
- return 1;
-}
-
-void
-slang_struct_destruct(slang_struct * stru)
-{
- slang_variable_scope_destruct(stru->fields);
- _slang_free(stru->fields);
- slang_struct_scope_destruct(stru->structs);
- _slang_free(stru->structs);
-}
-
-int
-slang_struct_copy(slang_struct * x, const slang_struct * y)
-{
- slang_struct z;
-
- if (!slang_struct_construct(&z))
- return 0;
- z.a_name = y->a_name;
- if (!slang_variable_scope_copy(z.fields, y->fields)) {
- slang_struct_destruct(&z);
- return 0;
- }
- if (!slang_struct_scope_copy(z.structs, y->structs)) {
- slang_struct_destruct(&z);
- return 0;
- }
- slang_struct_destruct(x);
- *x = z;
- return 1;
-}
-
-int
-slang_struct_equal(const slang_struct * x, const slang_struct * y)
-{
- GLuint i;
-
- if (x->fields->num_variables != y->fields->num_variables)
- return 0;
-
- for (i = 0; i < x->fields->num_variables; i++) {
- const slang_variable *varx = x->fields->variables[i];
- const slang_variable *vary = y->fields->variables[i];
-
- if (varx->a_name != vary->a_name)
- return 0;
- if (!slang_type_specifier_equal(&varx->type.specifier,
- &vary->type.specifier))
- return 0;
- if (varx->type.specifier.type == SLANG_SPEC_ARRAY)
- if (varx->array_len != vary->array_len)
- return GL_FALSE;
- }
- return 1;
-}
diff --git a/src/mesa/slang/slang_compile_struct.h b/src/mesa/slang/slang_compile_struct.h
deleted file mode 100644
index 7be6f204e11..00000000000
--- a/src/mesa/slang/slang_compile_struct.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-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.
- */
-
-#if !defined SLANG_COMPILE_STRUCT_H
-#define SLANG_COMPILE_STRUCT_H
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-#include "main/glheader.h"
-#include "slang_utility.h"
-
-struct slang_function_;
-
-typedef struct slang_struct_scope_
-{
- struct slang_struct_ *structs;
- GLuint num_structs;
- struct slang_struct_scope_ *outer_scope;
-} slang_struct_scope;
-
-extern GLvoid
-_slang_struct_scope_ctr (slang_struct_scope *);
-
-void slang_struct_scope_destruct (slang_struct_scope *);
-int slang_struct_scope_copy (slang_struct_scope *, const slang_struct_scope *);
-struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, slang_atom, int);
-
-typedef struct slang_struct_
-{
- slang_atom a_name;
- struct slang_variable_scope_ *fields;
- slang_struct_scope *structs;
- struct slang_function_ *constructor;
-} slang_struct;
-
-int slang_struct_construct (slang_struct *);
-void slang_struct_destruct (slang_struct *);
-int slang_struct_copy (slang_struct *, const slang_struct *);
-int slang_struct_equal (const slang_struct *, const slang_struct *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/mesa/slang/slang_compile_variable.c b/src/mesa/slang/slang_compile_variable.c
deleted file mode 100644
index 23c08a9039d..00000000000
--- a/src/mesa/slang/slang_compile_variable.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-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 slang_compile_variable.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_mem.h"
-
-
-static slang_variable *
-slang_variable_new(void)
-{
- slang_variable *v = (slang_variable *) _slang_alloc(sizeof(slang_variable));
- if (v) {
- if (!slang_variable_construct(v)) {
- _slang_free(v);
- v = NULL;
- }
- }
- return v;
-}
-
-
-static void
-slang_variable_delete(slang_variable * var)
-{
- slang_variable_destruct(var);
- _slang_free(var);
-}
-
-
-/*
- * slang_variable_scope
- */
-
-slang_variable_scope *
-_slang_variable_scope_new(slang_variable_scope *parent)
-{
- slang_variable_scope *s;
- s = (slang_variable_scope *) _slang_alloc(sizeof(slang_variable_scope));
- if (s)
- s->outer_scope = parent;
- return s;
-}
-
-
-GLvoid
-_slang_variable_scope_ctr(slang_variable_scope * self)
-{
- self->variables = NULL;
- self->num_variables = 0;
- self->outer_scope = NULL;
-}
-
-void
-slang_variable_scope_destruct(slang_variable_scope * scope)
-{
- unsigned int i;
-
- if (!scope)
- return;
- for (i = 0; i < scope->num_variables; i++) {
- if (scope->variables[i])
- slang_variable_delete(scope->variables[i]);
- }
- _slang_free(scope->variables);
- /* do not free scope->outer_scope */
-}
-
-int
-slang_variable_scope_copy(slang_variable_scope * x,
- const slang_variable_scope * y)
-{
- slang_variable_scope z;
- unsigned int i;
-
- _slang_variable_scope_ctr(&z);
- z.variables = (slang_variable **)
- _slang_alloc(y->num_variables * sizeof(slang_variable *));
- if (z.variables == NULL) {
- slang_variable_scope_destruct(&z);
- return 0;
- }
- for (z.num_variables = 0; z.num_variables < y->num_variables;
- z.num_variables++) {
- z.variables[z.num_variables] = slang_variable_new();
- if (!z.variables[z.num_variables]) {
- slang_variable_scope_destruct(&z);
- return 0;
- }
- }
- for (i = 0; i < z.num_variables; i++) {
- if (!slang_variable_copy(z.variables[i], y->variables[i])) {
- slang_variable_scope_destruct(&z);
- return 0;
- }
- }
- z.outer_scope = y->outer_scope;
- slang_variable_scope_destruct(x);
- *x = z;
- return 1;
-}
-
-
-/**
- * Grow the variable list by one.
- * \return pointer to space for the new variable (will be initialized)
- */
-slang_variable *
-slang_variable_scope_grow(slang_variable_scope *scope)
-{
- const int n = scope->num_variables;
- scope->variables = (slang_variable **)
- _slang_realloc(scope->variables,
- n * sizeof(slang_variable *),
- (n + 1) * sizeof(slang_variable *));
- if (!scope->variables)
- return NULL;
-
- scope->num_variables++;
-
- scope->variables[n] = slang_variable_new();
- if (!scope->variables[n])
- return NULL;
-
- return scope->variables[n];
-}
-
-
-
-/* slang_variable */
-
-int
-slang_variable_construct(slang_variable * var)
-{
- if (!slang_fully_specified_type_construct(&var->type))
- return 0;
- var->a_name = SLANG_ATOM_NULL;
- var->array_len = 0;
- var->initializer = NULL;
- var->size = 0;
- var->isTemp = GL_FALSE;
- var->store = NULL;
- var->declared = 0;
- return 1;
-}
-
-
-void
-slang_variable_destruct(slang_variable * var)
-{
- slang_fully_specified_type_destruct(&var->type);
- if (var->initializer != NULL) {
- slang_operation_destruct(var->initializer);
- _slang_free(var->initializer);
- }
-#if 0
- if (var->aux) {
- free(var->aux);
- }
-#endif
-}
-
-
-int
-slang_variable_copy(slang_variable * x, const slang_variable * y)
-{
- slang_variable z;
-
- if (!slang_variable_construct(&z))
- return 0;
- if (!slang_fully_specified_type_copy(&z.type, &y->type)) {
- slang_variable_destruct(&z);
- return 0;
- }
- z.a_name = y->a_name;
- z.array_len = y->array_len;
- if (y->initializer != NULL) {
- z.initializer
- = (slang_operation *) _slang_alloc(sizeof(slang_operation));
- if (z.initializer == NULL) {
- slang_variable_destruct(&z);
- return 0;
- }
- if (!slang_operation_construct(z.initializer)) {
- _slang_free(z.initializer);
- slang_variable_destruct(&z);
- return 0;
- }
- if (!slang_operation_copy(z.initializer, y->initializer)) {
- slang_variable_destruct(&z);
- return 0;
- }
- }
- z.size = y->size;
- slang_variable_destruct(x);
- *x = z;
- return 1;
-}
-
-
-/**
- * Search for named variable in given scope.
- * \param all if true, search parent scopes too.
- */
-slang_variable *
-_slang_variable_locate(const slang_variable_scope * scope,
- const slang_atom a_name, GLboolean all)
-{
- while (scope) {
- GLuint i;
- for (i = 0; i < scope->num_variables; i++)
- if (a_name == scope->variables[i]->a_name)
- return scope->variables[i];
- if (all)
- scope = scope->outer_scope;
- else
- scope = NULL;
- }
- return NULL;
-}
diff --git a/src/mesa/slang/slang_compile_variable.h b/src/mesa/slang/slang_compile_variable.h
deleted file mode 100644
index 48dc6efca4b..00000000000
--- a/src/mesa/slang/slang_compile_variable.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 2005-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 SLANG_COMPILE_VARIABLE_H
-#define SLANG_COMPILE_VARIABLE_H
-
-
-#include "main/glheader.h"
-#include "slang_typeinfo.h"
-#include "slang_utility.h"
-
-
-/**
- * A shading language program variable.
- */
-typedef struct slang_variable_
-{
- slang_fully_specified_type type; /**< Variable's data type */
- slang_atom a_name; /**< The variable's name (char *) */
- GLuint array_len; /**< only if type == SLANG_SPEC_ARRAy */
- struct slang_operation_ *initializer; /**< Optional initializer code */
- GLuint size; /**< Variable's size in bytes */
- GLboolean is_global;
- GLboolean isTemp; /**< a named temporary (__resultTmp) */
- GLboolean declared; /**< has the var been declared? */
- struct slang_ir_storage_ *store; /**< Storage for this var */
-} slang_variable;
-
-
-/**
- * Basically a list of variables, with a pointer to the parent scope.
- */
-typedef struct slang_variable_scope_
-{
- slang_variable **variables; /**< Array [num_variables] of ptrs to vars */
- GLuint num_variables;
- struct slang_variable_scope_ *outer_scope;
-} slang_variable_scope;
-
-
-extern slang_variable_scope *
-_slang_variable_scope_new(slang_variable_scope *parent);
-
-extern GLvoid
-_slang_variable_scope_ctr(slang_variable_scope *);
-
-extern void
-slang_variable_scope_destruct(slang_variable_scope *);
-
-extern int
-slang_variable_scope_copy(slang_variable_scope *,
- const slang_variable_scope *);
-
-extern slang_variable *
-slang_variable_scope_grow(slang_variable_scope *);
-
-extern int
-slang_variable_construct(slang_variable *);
-
-extern void
-slang_variable_destruct(slang_variable *);
-
-extern int
-slang_variable_copy(slang_variable *, const slang_variable *);
-
-extern slang_variable *
-_slang_variable_locate(const slang_variable_scope *, const slang_atom a_name,
- GLboolean all);
-
-
-#endif /* SLANG_COMPILE_VARIABLE_H */
diff --git a/src/mesa/slang/slang_emit.c b/src/mesa/slang/slang_emit.c
deleted file mode 100644
index a9aa6fe1c3a..00000000000
--- a/src/mesa/slang/slang_emit.c
+++ /dev/null
@@ -1,2686 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2008 VMware, 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.
- */
-
-/**
- * \file slang_emit.c
- * Emit program instructions (PI code) from IR trees.
- * \author Brian Paul
- */
-
-/***
- *** NOTES
- ***
- *** To emit GPU instructions, we basically just do an in-order traversal
- *** of the IR tree.
- ***/
-
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "program/program.h"
-#include "program/prog_instruction.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-#include "slang_builtin.h"
-#include "slang_emit.h"
-#include "slang_mem.h"
-
-
-#define PEEPHOLE_OPTIMIZATIONS 1
-#define ANNOTATE 0
-
-
-typedef struct
-{
- slang_info_log *log;
- slang_var_table *vt;
- struct gl_program *prog;
- struct gl_program **Subroutines;
- GLuint NumSubroutines;
-
- GLuint MaxInstructions; /**< size of prog->Instructions[] buffer */
-
- GLboolean UnresolvedFunctions;
-
- /* code-gen options */
- GLboolean EmitHighLevelInstructions;
- GLboolean EmitCondCodes;
- GLboolean EmitComments;
- GLboolean EmitBeginEndSub; /* XXX TEMPORARY */
-} slang_emit_info;
-
-
-
-static struct gl_program *
-new_subroutine(slang_emit_info *emitInfo, GLuint *id)
-{
- GET_CURRENT_CONTEXT(ctx);
- const GLuint n = emitInfo->NumSubroutines;
-
- emitInfo->Subroutines = (struct gl_program **)
- _mesa_realloc(emitInfo->Subroutines,
- n * sizeof(struct gl_program *),
- (n + 1) * sizeof(struct gl_program *));
- emitInfo->Subroutines[n] = ctx->Driver.NewProgram(ctx, emitInfo->prog->Target, 0);
- emitInfo->Subroutines[n]->Parameters = emitInfo->prog->Parameters;
- emitInfo->NumSubroutines++;
- *id = n;
- return emitInfo->Subroutines[n];
-}
-
-
-/**
- * Convert a writemask to a swizzle. Used for testing cond codes because
- * we only want to test the cond code component(s) that was set by the
- * previous instruction.
- */
-static GLuint
-writemask_to_swizzle(GLuint writemask)
-{
- if (writemask == WRITEMASK_X)
- return SWIZZLE_XXXX;
- if (writemask == WRITEMASK_Y)
- return SWIZZLE_YYYY;
- if (writemask == WRITEMASK_Z)
- return SWIZZLE_ZZZZ;
- if (writemask == WRITEMASK_W)
- return SWIZZLE_WWWW;
- return SWIZZLE_XYZW; /* shouldn't be hit */
-}
-
-
-/**
- * Convert a swizzle mask to a writemask.
- * Note that the slang_ir_storage->Swizzle field can represent either a
- * swizzle mask or a writemask, depending on how it's used. For example,
- * when we parse "direction.yz" alone, we don't know whether .yz is a
- * writemask or a swizzle. In this case, we encode ".yz" in store->Swizzle
- * as a swizzle mask (.yz?? actually). Later, if direction.yz is used as
- * an R-value, we use store->Swizzle as-is. Otherwise, if direction.yz is
- * used as an L-value, we convert it to a writemask.
- */
-static GLuint
-swizzle_to_writemask(GLuint swizzle)
-{
- GLuint i, writemask = 0x0;
- for (i = 0; i < 4; i++) {
- GLuint swz = GET_SWZ(swizzle, i);
- if (swz <= SWIZZLE_W) {
- writemask |= (1 << swz);
- }
- }
- return writemask;
-}
-
-
-/**
- * Swizzle a swizzle (function composition).
- * That is, return swz2(swz1), or said another way: swz1.szw2
- * Example: swizzle_swizzle(".zwxx", ".xxyw") yields ".zzwx"
- */
-GLuint
-_slang_swizzle_swizzle(GLuint swz1, GLuint swz2)
-{
- GLuint i, swz, s[4];
- for (i = 0; i < 4; i++) {
- GLuint c = GET_SWZ(swz2, i);
- if (c <= SWIZZLE_W)
- s[i] = GET_SWZ(swz1, c);
- else
- s[i] = c;
- }
- swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
- return swz;
-}
-
-
-/**
- * Return the default swizzle mask for accessing a variable of the
- * given size (in floats). If size = 1, comp is used to identify
- * which component [0..3] of the register holds the variable.
- */
-GLuint
-_slang_var_swizzle(GLint size, GLint comp)
-{
- switch (size) {
- case 1:
- return MAKE_SWIZZLE4(comp, SWIZZLE_NIL, SWIZZLE_NIL, SWIZZLE_NIL);
- case 2:
- return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_NIL, SWIZZLE_NIL);
- case 3:
- return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_NIL);
- default:
- return SWIZZLE_XYZW;
- }
-}
-
-
-
-/**
- * Allocate storage for the given node (if it hasn't already been allocated).
- *
- * Typically this is temporary storage for an intermediate result (such as
- * for a multiply or add, etc).
- *
- * If n->Store does not exist it will be created and will be of the size
- * specified by defaultSize.
- */
-static GLboolean
-alloc_node_storage(slang_emit_info *emitInfo, slang_ir_node *n,
- GLint defaultSize)
-{
- assert(!n->Var);
- if (!n->Store) {
- assert(defaultSize > 0);
- n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, defaultSize);
- if (!n->Store) {
- return GL_FALSE;
- }
- }
-
- /* now allocate actual register(s). I.e. set n->Store->Index >= 0 */
- if (n->Store->Index < 0) {
- if (!_slang_alloc_temp(emitInfo->vt, n->Store)) {
- slang_info_log_error(emitInfo->log,
- "Ran out of registers, too many temporaries");
- _slang_free(n->Store);
- n->Store = NULL;
- return GL_FALSE;
- }
- }
- return GL_TRUE;
-}
-
-
-/**
- * Free temporary storage, if n->Store is, in fact, temp storage.
- * Otherwise, no-op.
- */
-static void
-free_node_storage(slang_var_table *vt, slang_ir_node *n)
-{
- if (n->Store->File == PROGRAM_TEMPORARY &&
- n->Store->Index >= 0 &&
- n->Opcode != IR_SWIZZLE) {
- if (_slang_is_temp(vt, n->Store)) {
- _slang_free_temp(vt, n->Store);
- n->Store->Index = -1;
- n->Store = NULL; /* XXX this may not be needed */
- }
- }
-}
-
-
-/**
- * Helper function to allocate a short-term temporary.
- * Free it with _slang_free_temp().
- */
-static GLboolean
-alloc_local_temp(slang_emit_info *emitInfo, slang_ir_storage *temp, GLint size)
-{
- assert(size >= 1);
- assert(size <= 4);
- memset(temp, 0, sizeof(*temp));
- temp->Size = size;
- temp->File = PROGRAM_TEMPORARY;
- temp->Index = -1;
- return _slang_alloc_temp(emitInfo->vt, temp);
-}
-
-
-/**
- * Remove any SWIZZLE_NIL terms from given swizzle mask.
- * For a swizzle like .z??? generate .zzzz (replicate single component).
- * Else, for .wx?? generate .wxzw (insert default component for the position).
- */
-static GLuint
-fix_swizzle(GLuint swizzle)
-{
- GLuint c0 = GET_SWZ(swizzle, 0),
- c1 = GET_SWZ(swizzle, 1),
- c2 = GET_SWZ(swizzle, 2),
- c3 = GET_SWZ(swizzle, 3);
- if (c1 == SWIZZLE_NIL && c2 == SWIZZLE_NIL && c3 == SWIZZLE_NIL) {
- /* smear first component across all positions */
- c1 = c2 = c3 = c0;
- }
- else {
- /* insert default swizzle components */
- if (c0 == SWIZZLE_NIL)
- c0 = SWIZZLE_X;
- if (c1 == SWIZZLE_NIL)
- c1 = SWIZZLE_Y;
- if (c2 == SWIZZLE_NIL)
- c2 = SWIZZLE_Z;
- if (c3 == SWIZZLE_NIL)
- c3 = SWIZZLE_W;
- }
- return MAKE_SWIZZLE4(c0, c1, c2, c3);
-}
-
-
-
-/**
- * Convert IR storage to an instruction dst register.
- */
-static void
-storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st)
-{
- const GLboolean relAddr = st->RelAddr;
- const GLint size = st->Size;
- GLint index = st->Index;
- GLuint swizzle = st->Swizzle;
-
- assert(index >= 0);
- /* if this is storage relative to some parent storage, walk up the tree */
- while (st->Parent) {
- st = st->Parent;
- assert(st->Index >= 0);
- index += st->Index;
- swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle);
- }
-
- assert(st->File != PROGRAM_UNDEFINED);
- dst->File = st->File;
-
- assert(index >= 0);
- dst->Index = index;
-
- assert(size >= 1);
- assert(size <= 4);
-
- if (swizzle != SWIZZLE_XYZW) {
- dst->WriteMask = swizzle_to_writemask(swizzle);
- }
- else {
- switch (size) {
- case 1:
- dst->WriteMask = WRITEMASK_X << GET_SWZ(st->Swizzle, 0);
- break;
- case 2:
- dst->WriteMask = WRITEMASK_XY;
- break;
- case 3:
- dst->WriteMask = WRITEMASK_XYZ;
- break;
- case 4:
- dst->WriteMask = WRITEMASK_XYZW;
- break;
- default:
- ; /* error would have been caught above */
- }
- }
-
- dst->RelAddr = relAddr;
-}
-
-
-/**
- * Convert IR storage to an instruction src register.
- */
-static void
-storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
-{
- const GLboolean relAddr = st->RelAddr;
- GLint index = st->Index;
- GLuint swizzle = st->Swizzle;
-
- /* if this is storage relative to some parent storage, walk up the tree */
- assert(index >= 0);
- while (st->Parent) {
- st = st->Parent;
- if (st->Index < 0) {
- /* an error should have been reported already */
- return;
- }
- assert(st->Index >= 0);
- index += st->Index;
- swizzle = _slang_swizzle_swizzle(fix_swizzle(st->Swizzle), swizzle);
- }
-
- assert(st->File >= 0);
-#if 1 /* XXX temporary */
- if (st->File == PROGRAM_UNDEFINED) {
- slang_ir_storage *st0 = (slang_ir_storage *) st;
- st0->File = PROGRAM_TEMPORARY;
- }
-#endif
- assert(st->File < PROGRAM_FILE_MAX);
- src->File = st->File;
-
- assert(index >= 0);
- src->Index = index;
-
- swizzle = fix_swizzle(swizzle);
- assert(GET_SWZ(swizzle, 0) <= SWIZZLE_W);
- assert(GET_SWZ(swizzle, 1) <= SWIZZLE_W);
- assert(GET_SWZ(swizzle, 2) <= SWIZZLE_W);
- assert(GET_SWZ(swizzle, 3) <= SWIZZLE_W);
- src->Swizzle = swizzle;
-
- src->HasIndex2 = st->Is2D;
- src->Index2 = st->Index2;
-
- src->RelAddr = relAddr;
-}
-
-
-/*
- * Setup storage pointing to a scalar constant/literal.
- */
-static void
-constant_to_storage(slang_emit_info *emitInfo,
- GLfloat val,
- slang_ir_storage *store)
-{
- GLuint swizzle;
- GLint reg;
- GLfloat value[4];
-
- value[0] = val;
- reg = _mesa_add_unnamed_constant(emitInfo->prog->Parameters,
- value, 1, &swizzle);
-
- memset(store, 0, sizeof(*store));
- store->File = PROGRAM_CONSTANT;
- store->Index = reg;
- store->Swizzle = swizzle;
-}
-
-
-/**
- * Add new instruction at end of given program.
- * \param prog the program to append instruction onto
- * \param opcode opcode for the new instruction
- * \return pointer to the new instruction
- */
-static struct prog_instruction *
-new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode)
-{
- struct gl_program *prog = emitInfo->prog;
- struct prog_instruction *inst;
-
-#if 0
- /* print prev inst */
- if (prog->NumInstructions > 0) {
- _mesa_print_instruction(prog->Instructions + prog->NumInstructions - 1);
- }
-#endif
- assert(prog->NumInstructions <= emitInfo->MaxInstructions);
-
- if (prog->NumInstructions == emitInfo->MaxInstructions) {
- /* grow the instruction buffer */
- emitInfo->MaxInstructions += 20;
- prog->Instructions =
- _mesa_realloc_instructions(prog->Instructions,
- prog->NumInstructions,
- emitInfo->MaxInstructions);
- if (!prog->Instructions) {
- return NULL;
- }
- }
-
- inst = prog->Instructions + prog->NumInstructions;
- prog->NumInstructions++;
- _mesa_init_instructions(inst, 1);
- inst->Opcode = opcode;
- inst->BranchTarget = -1; /* invalid */
- /*
- printf("New inst %d: %p %s\n", prog->NumInstructions-1,(void*)inst,
- _mesa_opcode_string(inst->Opcode));
- */
- return inst;
-}
-
-
-static struct prog_instruction *
-emit_arl_load(slang_emit_info *emitInfo,
- gl_register_file file, GLint index, GLuint swizzle)
-{
- struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ARL);
- if (inst) {
- inst->SrcReg[0].File = file;
- inst->SrcReg[0].Index = index;
- inst->SrcReg[0].Swizzle = fix_swizzle(swizzle);
- inst->DstReg.File = PROGRAM_ADDRESS;
- inst->DstReg.Index = 0;
- inst->DstReg.WriteMask = WRITEMASK_X;
- }
- return inst;
-}
-
-
-/**
- * Emit a new instruction with given opcode, operands.
- * At this point the instruction may have multiple indirect register
- * loads/stores. We convert those into ARL loads and address-relative
- * operands. See comments inside.
- * At some point in the future we could directly emit indirectly addressed
- * registers in Mesa GPU instructions.
- */
-static struct prog_instruction *
-emit_instruction(slang_emit_info *emitInfo,
- gl_inst_opcode opcode,
- const slang_ir_storage *dst,
- const slang_ir_storage *src0,
- const slang_ir_storage *src1,
- const slang_ir_storage *src2)
-{
- struct prog_instruction *inst;
- GLuint numIndirect = 0;
- const slang_ir_storage *src[3];
- slang_ir_storage newSrc[3], newDst;
- GLuint i;
- GLboolean isTemp[3];
-
- isTemp[0] = isTemp[1] = isTemp[2] = GL_FALSE;
-
- src[0] = src0;
- src[1] = src1;
- src[2] = src2;
-
- /* count up how many operands are indirect loads */
- for (i = 0; i < 3; i++) {
- if (src[i] && src[i]->IsIndirect)
- numIndirect++;
- }
- if (dst && dst->IsIndirect)
- numIndirect++;
-
- /* Take special steps for indirect register loads.
- * If we had multiple address registers this would be simpler.
- * For example, this GLSL code:
- * x[i] = y[j] + z[k];
- * would translate into something like:
- * ARL ADDR.x, i;
- * ARL ADDR.y, j;
- * ARL ADDR.z, k;
- * ADD TEMP[ADDR.x+5], TEMP[ADDR.y+9], TEMP[ADDR.z+4];
- * But since we currently only have one address register we have to do this:
- * ARL ADDR.x, i;
- * MOV t1, TEMP[ADDR.x+9];
- * ARL ADDR.x, j;
- * MOV t2, TEMP[ADDR.x+4];
- * ARL ADDR.x, k;
- * ADD TEMP[ADDR.x+5], t1, t2;
- * The code here figures this out...
- */
- if (numIndirect > 0) {
- for (i = 0; i < 3; i++) {
- if (src[i] && src[i]->IsIndirect) {
- /* load the ARL register with the indirect register */
- emit_arl_load(emitInfo,
- src[i]->IndirectFile,
- src[i]->IndirectIndex,
- src[i]->IndirectSwizzle);
-
- if (numIndirect > 1) {
- /* Need to load src[i] into a temporary register */
- slang_ir_storage srcRelAddr;
- alloc_local_temp(emitInfo, &newSrc[i], src[i]->Size);
- isTemp[i] = GL_TRUE;
-
- /* set RelAddr flag on src register */
- srcRelAddr = *src[i];
- srcRelAddr.RelAddr = GL_TRUE;
- srcRelAddr.IsIndirect = GL_FALSE; /* not really needed */
-
- /* MOV newSrc, srcRelAddr; */
- inst = emit_instruction(emitInfo,
- OPCODE_MOV,
- &newSrc[i],
- &srcRelAddr,
- NULL,
- NULL);
- if (!inst) {
- return NULL;
- }
-
- src[i] = &newSrc[i];
- }
- else {
- /* just rewrite the src[i] storage to be ARL-relative */
- newSrc[i] = *src[i];
- newSrc[i].RelAddr = GL_TRUE;
- newSrc[i].IsIndirect = GL_FALSE; /* not really needed */
- src[i] = &newSrc[i];
- }
- }
- }
- }
-
- /* Take special steps for indirect dest register write */
- if (dst && dst->IsIndirect) {
- /* load the ARL register with the indirect register */
- emit_arl_load(emitInfo,
- dst->IndirectFile,
- dst->IndirectIndex,
- dst->IndirectSwizzle);
- newDst = *dst;
- newDst.RelAddr = GL_TRUE;
- newDst.IsIndirect = GL_FALSE;
- dst = &newDst;
- }
-
- /* OK, emit the instruction and its dst, src regs */
- inst = new_instruction(emitInfo, opcode);
- if (!inst)
- return NULL;
-
- if (dst)
- storage_to_dst_reg(&inst->DstReg, dst);
-
- for (i = 0; i < 3; i++) {
- if (src[i])
- storage_to_src_reg(&inst->SrcReg[i], src[i]);
- }
-
- /* Free any temp registers that we allocated above */
- for (i = 0; i < 3; i++) {
- if (isTemp[i])
- _slang_free_temp(emitInfo->vt, &newSrc[i]);
- }
-
- return inst;
-}
-
-
-
-/**
- * Put a comment on the given instruction.
- */
-static void
-inst_comment(struct prog_instruction *inst, const char *comment)
-{
- if (inst)
- inst->Comment = _mesa_strdup(comment);
-}
-
-
-
-/**
- * Return pointer to last instruction in program.
- */
-static struct prog_instruction *
-prev_instruction(slang_emit_info *emitInfo)
-{
- struct gl_program *prog = emitInfo->prog;
- if (prog->NumInstructions == 0)
- return NULL;
- else
- return prog->Instructions + prog->NumInstructions - 1;
-}
-
-
-static struct prog_instruction *
-emit(slang_emit_info *emitInfo, slang_ir_node *n);
-
-
-/**
- * Return an annotation string for given node's storage.
- */
-static char *
-storage_annotation(const slang_ir_node *n, const struct gl_program *prog)
-{
-#if ANNOTATE
- const slang_ir_storage *st = n->Store;
- static char s[100] = "";
-
- if (!st)
- return _mesa_strdup("");
-
- switch (st->File) {
- case PROGRAM_CONSTANT:
- if (st->Index >= 0) {
- const GLfloat *val = prog->Parameters->ParameterValues[st->Index];
- if (st->Swizzle == SWIZZLE_NOOP)
- _mesa_snprintf(s, sizeof(s), "{%g, %g, %g, %g}", val[0], val[1], val[2], val[3]);
- else {
- _mesa_snprintf(s, sizeof(s), "%g", val[GET_SWZ(st->Swizzle, 0)]);
- }
- }
- break;
- case PROGRAM_TEMPORARY:
- if (n->Var)
- _mesa_snprintf(s, sizeof(s), "%s", (char *) n->Var->a_name);
- else
- _mesa_snprintf(s, sizeof(s), "t[%d]", st->Index);
- break;
- case PROGRAM_STATE_VAR:
- case PROGRAM_UNIFORM:
- _mesa_snprintf(s, sizeof(s), "%s", prog->Parameters->Parameters[st->Index].Name);
- break;
- case PROGRAM_VARYING:
- _mesa_snprintf(s, sizeof(s), "%s", prog->Varying->Parameters[st->Index].Name);
- break;
- case PROGRAM_INPUT:
- _mesa_snprintf(s, sizeof(s), "input[%d]", st->Index);
- break;
- case PROGRAM_OUTPUT:
- _mesa_snprintf(s, sizeof(s), "output[%d]", st->Index);
- break;
- default:
- s[0] = 0;
- }
- return _mesa_strdup(s);
-#else
- return NULL;
-#endif
-}
-
-
-/**
- * Return an annotation string for an instruction.
- */
-static char *
-instruction_annotation(gl_inst_opcode opcode, char *dstAnnot,
- char *srcAnnot0, char *srcAnnot1, char *srcAnnot2)
-{
-#if ANNOTATE
- const char *operator;
- char *s;
- int len = 50;
-
- if (dstAnnot)
- len += strlen(dstAnnot);
- else
- dstAnnot = _mesa_strdup("");
-
- if (srcAnnot0)
- len += strlen(srcAnnot0);
- else
- srcAnnot0 = _mesa_strdup("");
-
- if (srcAnnot1)
- len += strlen(srcAnnot1);
- else
- srcAnnot1 = _mesa_strdup("");
-
- if (srcAnnot2)
- len += strlen(srcAnnot2);
- else
- srcAnnot2 = _mesa_strdup("");
-
- switch (opcode) {
- case OPCODE_ADD:
- operator = "+";
- break;
- case OPCODE_SUB:
- operator = "-";
- break;
- case OPCODE_MUL:
- operator = "*";
- break;
- case OPCODE_DP2:
- operator = "DP2";
- break;
- case OPCODE_DP3:
- operator = "DP3";
- break;
- case OPCODE_DP4:
- operator = "DP4";
- break;
- case OPCODE_XPD:
- operator = "XPD";
- break;
- case OPCODE_RSQ:
- operator = "RSQ";
- break;
- case OPCODE_SGT:
- operator = ">";
- break;
- default:
- operator = ",";
- }
-
- s = (char *) malloc(len);
- _mesa_snprintf(s, len, "%s = %s %s %s %s", dstAnnot,
- srcAnnot0, operator, srcAnnot1, srcAnnot2);
-
- free(dstAnnot);
- free(srcAnnot0);
- free(srcAnnot1);
- free(srcAnnot2);
-
- return s;
-#else
- return NULL;
-#endif
-}
-
-
-/**
- * Emit an instruction that's just a comment.
- */
-static struct prog_instruction *
-emit_comment(slang_emit_info *emitInfo, const char *comment)
-{
- struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP);
- if (inst) {
- inst_comment(inst, comment);
- }
- return inst;
-}
-
-
-/**
- * Generate code for a simple arithmetic instruction.
- * Either 1, 2 or 3 operands.
- */
-static struct prog_instruction *
-emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- const slang_ir_info *info = _slang_ir_info(n->Opcode);
- struct prog_instruction *inst;
- GLuint i;
-
- assert(info);
- assert(info->InstOpcode != OPCODE_NOP);
-
-#if PEEPHOLE_OPTIMIZATIONS
- /* Look for MAD opportunity */
- if (info->NumParams == 2 &&
- n->Opcode == IR_ADD && n->Children[0]->Opcode == IR_MUL) {
- /* found pattern IR_ADD(IR_MUL(A, B), C) */
- emit(emitInfo, n->Children[0]->Children[0]); /* A */
- emit(emitInfo, n->Children[0]->Children[1]); /* B */
- emit(emitInfo, n->Children[1]); /* C */
- if (!alloc_node_storage(emitInfo, n, -1)) { /* dest */
- return NULL;
- }
-
- inst = emit_instruction(emitInfo,
- OPCODE_MAD,
- n->Store,
- n->Children[0]->Children[0]->Store,
- n->Children[0]->Children[1]->Store,
- n->Children[1]->Store);
-
- free_node_storage(emitInfo->vt, n->Children[0]->Children[0]);
- free_node_storage(emitInfo->vt, n->Children[0]->Children[1]);
- free_node_storage(emitInfo->vt, n->Children[1]);
- return inst;
- }
-
- if (info->NumParams == 2 &&
- n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) {
- /* found pattern IR_ADD(A, IR_MUL(B, C)) */
- emit(emitInfo, n->Children[0]); /* A */
- emit(emitInfo, n->Children[1]->Children[0]); /* B */
- emit(emitInfo, n->Children[1]->Children[1]); /* C */
- if (!alloc_node_storage(emitInfo, n, -1)) { /* dest */
- return NULL;
- }
-
- inst = emit_instruction(emitInfo,
- OPCODE_MAD,
- n->Store,
- n->Children[1]->Children[0]->Store,
- n->Children[1]->Children[1]->Store,
- n->Children[0]->Store);
-
- free_node_storage(emitInfo->vt, n->Children[1]->Children[0]);
- free_node_storage(emitInfo->vt, n->Children[1]->Children[1]);
- free_node_storage(emitInfo->vt, n->Children[0]);
- return inst;
- }
-#endif
-
- /* gen code for children, may involve temp allocation */
- for (i = 0; i < info->NumParams; i++) {
- emit(emitInfo, n->Children[i]);
- if (!n->Children[i] || !n->Children[i]->Store) {
- /* error recovery */
- return NULL;
- }
- }
-
- /* result storage */
- if (!alloc_node_storage(emitInfo, n, -1)) {
- return NULL;
- }
-
- inst = emit_instruction(emitInfo,
- info->InstOpcode,
- n->Store, /* dest */
- (info->NumParams > 0 ? n->Children[0]->Store : NULL),
- (info->NumParams > 1 ? n->Children[1]->Store : NULL),
- (info->NumParams > 2 ? n->Children[2]->Store : NULL)
- );
-
- /* free temps */
- for (i = 0; i < info->NumParams; i++)
- free_node_storage(emitInfo->vt, n->Children[i]);
-
- return inst;
-}
-
-
-/**
- * Emit code for == and != operators. These could normally be handled
- * by emit_arith() except we need to be able to handle structure comparisons.
- */
-static struct prog_instruction *
-emit_compare(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst = NULL;
- GLint size;
-
- assert(n->Opcode == IR_EQUAL || n->Opcode == IR_NOTEQUAL);
-
- /* gen code for children */
- emit(emitInfo, n->Children[0]);
- emit(emitInfo, n->Children[1]);
-
- if (n->Children[0]->Store->Size != n->Children[1]->Store->Size) {
- /* XXX this error should have been caught in slang_codegen.c */
- slang_info_log_error(emitInfo->log, "invalid operands to == or !=");
- n->Store = NULL;
- return NULL;
- }
-
- /* final result is 1 bool */
- if (!alloc_node_storage(emitInfo, n, 1))
- return NULL;
-
- size = n->Children[0]->Store->Size;
-
- if (size == 1) {
- gl_inst_opcode opcode = n->Opcode == IR_EQUAL ? OPCODE_SEQ : OPCODE_SNE;
- inst = emit_instruction(emitInfo,
- opcode,
- n->Store, /* dest */
- n->Children[0]->Store,
- n->Children[1]->Store,
- NULL);
- }
- else if (size <= 4) {
- /* compare two vectors.
- * Unfortunately, there's no instruction to compare vectors and
- * return a scalar result. Do it with some compare and dot product
- * instructions...
- */
- GLuint swizzle;
- gl_inst_opcode dotOp;
- slang_ir_storage tempStore;
-
- if (!alloc_local_temp(emitInfo, &tempStore, 4)) {
- n->Store = NULL;
- return NULL;
- /* out of temps */
- }
-
- if (size == 4) {
- dotOp = OPCODE_DP4;
- swizzle = SWIZZLE_XYZW;
- }
- else if (size == 3) {
- dotOp = OPCODE_DP3;
- swizzle = SWIZZLE_XYZW;
- }
- else {
- assert(size == 2);
- dotOp = OPCODE_DP3; /* XXX use OPCODE_DP2 eventually */
- swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y);
- }
-
- /* Compute inequality (temp = (A != B)) */
- inst = emit_instruction(emitInfo,
- OPCODE_SNE,
- &tempStore,
- n->Children[0]->Store,
- n->Children[1]->Store,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, "Compare values");
-
- /* Compute val = DOT(temp, temp) (reduction) */
- inst = emit_instruction(emitInfo,
- dotOp,
- n->Store,
- &tempStore,
- &tempStore,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/
- inst_comment(inst, "Reduce vec to bool");
-
- _slang_free_temp(emitInfo->vt, &tempStore); /* free temp */
-
- if (n->Opcode == IR_EQUAL) {
- /* compute val = !val.x with SEQ val, val, 0; */
- slang_ir_storage zero;
- constant_to_storage(emitInfo, 0.0, &zero);
- inst = emit_instruction(emitInfo,
- OPCODE_SEQ,
- n->Store, /* dest */
- n->Store,
- &zero,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, "Invert true/false");
- }
- }
- else {
- /* size > 4, struct or array compare.
- * XXX this won't work reliably for structs with padding!!
- */
- GLint i, num = (n->Children[0]->Store->Size + 3) / 4;
- slang_ir_storage accTemp, sneTemp;
-
- if (!alloc_local_temp(emitInfo, &accTemp, 4))
- return NULL;
-
- if (!alloc_local_temp(emitInfo, &sneTemp, 4))
- return NULL;
-
- for (i = 0; i < num; i++) {
- slang_ir_storage srcStore0 = *n->Children[0]->Store;
- slang_ir_storage srcStore1 = *n->Children[1]->Store;
- srcStore0.Index += i;
- srcStore1.Index += i;
-
- if (i == 0) {
- /* SNE accTemp, left[i], right[i] */
- inst = emit_instruction(emitInfo, OPCODE_SNE,
- &accTemp, /* dest */
- &srcStore0,
- &srcStore1,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, "Begin struct/array comparison");
- }
- else {
- /* SNE sneTemp, left[i], right[i] */
- inst = emit_instruction(emitInfo, OPCODE_SNE,
- &sneTemp, /* dest */
- &srcStore0,
- &srcStore1,
- NULL);
- if (!inst) {
- return NULL;
- }
- /* ADD accTemp, accTemp, sneTemp; # like logical-OR */
- inst = emit_instruction(emitInfo, OPCODE_ADD,
- &accTemp, /* dest */
- &accTemp,
- &sneTemp,
- NULL);
- if (!inst) {
- return NULL;
- }
- }
- }
-
- /* compute accTemp.x || accTemp.y || accTemp.z || accTemp.w with DOT4 */
- inst = emit_instruction(emitInfo, OPCODE_DP4,
- n->Store,
- &accTemp,
- &accTemp,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, "End struct/array comparison");
-
- if (n->Opcode == IR_EQUAL) {
- /* compute tmp.x = !tmp.x via tmp.x = (tmp.x == 0) */
- slang_ir_storage zero;
- constant_to_storage(emitInfo, 0.0, &zero);
- inst = emit_instruction(emitInfo, OPCODE_SEQ,
- n->Store, /* dest */
- n->Store,
- &zero,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, "Invert true/false");
- }
-
- _slang_free_temp(emitInfo->vt, &accTemp);
- _slang_free_temp(emitInfo->vt, &sneTemp);
- }
-
- /* free temps */
- free_node_storage(emitInfo->vt, n->Children[0]);
- free_node_storage(emitInfo->vt, n->Children[1]);
-
- return inst;
-}
-
-
-
-/**
- * Generate code for an IR_CLAMP instruction.
- */
-static struct prog_instruction *
-emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst;
- slang_ir_node tmpNode;
-
- assert(n->Opcode == IR_CLAMP);
- /* ch[0] = value
- * ch[1] = min limit
- * ch[2] = max limit
- */
-
- inst = emit(emitInfo, n->Children[0]);
-
- /* If lower limit == 0.0 and upper limit == 1.0,
- * set prev instruction's SaturateMode field to SATURATE_ZERO_ONE.
- * Else,
- * emit OPCODE_MIN, OPCODE_MAX sequence.
- */
-#if 0
- /* XXX this isn't quite finished yet */
- if (n->Children[1]->Opcode == IR_FLOAT &&
- n->Children[1]->Value[0] == 0.0 &&
- n->Children[1]->Value[1] == 0.0 &&
- n->Children[1]->Value[2] == 0.0 &&
- n->Children[1]->Value[3] == 0.0 &&
- n->Children[2]->Opcode == IR_FLOAT &&
- n->Children[2]->Value[0] == 1.0 &&
- n->Children[2]->Value[1] == 1.0 &&
- n->Children[2]->Value[2] == 1.0 &&
- n->Children[2]->Value[3] == 1.0) {
- if (!inst) {
- inst = prev_instruction(prog);
- }
- if (inst && inst->Opcode != OPCODE_NOP) {
- /* and prev instruction's DstReg matches n->Children[0]->Store */
- inst->SaturateMode = SATURATE_ZERO_ONE;
- n->Store = n->Children[0]->Store;
- return inst;
- }
- }
-#else
- (void) inst;
-#endif
-
- if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
- return NULL;
-
- emit(emitInfo, n->Children[1]);
- emit(emitInfo, n->Children[2]);
-
- /* Some GPUs don't allow reading from output registers. So if the
- * dest for this clamp() is an output reg, we can't use that reg for
- * the intermediate result. Use a temp register instead.
- */
- memset(&tmpNode, 0, sizeof(tmpNode));
- if (!alloc_node_storage(emitInfo, &tmpNode, n->Store->Size)) {
- return NULL;
- }
-
- /* tmp = max(ch[0], ch[1]) */
- inst = emit_instruction(emitInfo, OPCODE_MAX,
- tmpNode.Store, /* dest */
- n->Children[0]->Store,
- n->Children[1]->Store,
- NULL);
- if (!inst) {
- return NULL;
- }
-
- /* n->dest = min(tmp, ch[2]) */
- inst = emit_instruction(emitInfo, OPCODE_MIN,
- n->Store, /* dest */
- tmpNode.Store,
- n->Children[2]->Store,
- NULL);
-
- free_node_storage(emitInfo->vt, &tmpNode);
-
- return inst;
-}
-
-
-static struct prog_instruction *
-emit_negation(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- /* Implement as MOV dst, -src; */
- /* XXX we could look at the previous instruction and in some circumstances
- * modify it to accomplish the negation.
- */
- struct prog_instruction *inst;
-
- emit(emitInfo, n->Children[0]);
-
- if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
- return NULL;
-
- inst = emit_instruction(emitInfo,
- OPCODE_MOV,
- n->Store, /* dest */
- n->Children[0]->Store,
- NULL,
- NULL);
- if (inst) {
- inst->SrcReg[0].Negate = NEGATE_XYZW;
- }
- return inst;
-}
-
-
-static struct prog_instruction *
-emit_label(slang_emit_info *emitInfo, const slang_ir_node *n)
-{
- assert(n->Label);
-#if 0
- /* XXX this fails in loop tail code - investigate someday */
- assert(_slang_label_get_location(n->Label) < 0);
- _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
- emitInfo->prog);
-#else
- if (_slang_label_get_location(n->Label) < 0)
- _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
- emitInfo->prog);
-#endif
- return NULL;
-}
-
-
-/**
- * Emit code for a function call.
- * Note that for each time a function is called, we emit the function's
- * body code again because the set of available registers may be different.
- */
-static struct prog_instruction *
-emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct gl_program *progSave;
- struct prog_instruction *inst;
- GLuint subroutineId;
- GLuint maxInstSave;
-
- assert(n->Opcode == IR_CALL);
- assert(n->Label);
-
- /* save/push cur program */
- maxInstSave = emitInfo->MaxInstructions;
- progSave = emitInfo->prog;
-
- emitInfo->prog = new_subroutine(emitInfo, &subroutineId);
- emitInfo->MaxInstructions = emitInfo->prog->NumInstructions;
-
- _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
- emitInfo->prog);
-
- if (emitInfo->EmitBeginEndSub) {
- /* BGNSUB isn't a real instruction.
- * We require a label (i.e. "foobar:") though, if we're going to
- * print the program in the NV format. The BNGSUB instruction is
- * really just a NOP to attach the label to.
- */
- inst = new_instruction(emitInfo, OPCODE_BGNSUB);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, n->Label->Name);
- }
-
- /* body of function: */
- emit(emitInfo, n->Children[0]);
- n->Store = n->Children[0]->Store;
-
- /* add RET instruction now, if needed */
- inst = prev_instruction(emitInfo);
- if (inst && inst->Opcode != OPCODE_RET) {
- inst = new_instruction(emitInfo, OPCODE_RET);
- if (!inst) {
- return NULL;
- }
- }
-
- if (emitInfo->EmitBeginEndSub) {
- inst = new_instruction(emitInfo, OPCODE_ENDSUB);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, n->Label->Name);
- }
-
- /* pop/restore cur program */
- emitInfo->prog = progSave;
- emitInfo->MaxInstructions = maxInstSave;
-
- /* emit the function call */
- inst = new_instruction(emitInfo, OPCODE_CAL);
- if (!inst) {
- return NULL;
- }
- /* The branch target is just the subroutine number (changed later) */
- inst->BranchTarget = subroutineId;
- inst_comment(inst, n->Label->Name);
- assert(inst->BranchTarget >= 0);
-
- return inst;
-}
-
-
-/**
- * Emit code for a 'return' statement.
- */
-static struct prog_instruction *
-emit_return(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst;
- assert(n);
- assert(n->Opcode == IR_RETURN);
- assert(n->Label);
- inst = new_instruction(emitInfo, OPCODE_RET);
- if (inst) {
- inst->DstReg.CondMask = COND_TR; /* always return */
- }
- return inst;
-}
-
-
-static struct prog_instruction *
-emit_kill(slang_emit_info *emitInfo)
-{
- struct gl_fragment_program *fp;
- struct prog_instruction *inst;
- /* NV-KILL - discard fragment depending on condition code.
- * Note that ARB-KILL depends on sign of vector operand.
- */
- inst = new_instruction(emitInfo, OPCODE_KIL_NV);
- if (!inst) {
- return NULL;
- }
- inst->DstReg.CondMask = COND_TR; /* always kill */
-
- assert(emitInfo->prog->Target == GL_FRAGMENT_PROGRAM_ARB);
- fp = (struct gl_fragment_program *) emitInfo->prog;
- fp->UsesKill = GL_TRUE;
-
- return inst;
-}
-
-
-static struct prog_instruction *
-emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst;
- gl_inst_opcode opcode;
- GLboolean shadow = GL_FALSE;
-
- switch (n->Opcode) {
- case IR_TEX:
- opcode = OPCODE_TEX;
- break;
- case IR_TEX_SH:
- opcode = OPCODE_TEX;
- shadow = GL_TRUE;
- break;
- case IR_TEXB:
- opcode = OPCODE_TXB;
- break;
- case IR_TEXB_SH:
- opcode = OPCODE_TXB;
- shadow = GL_TRUE;
- break;
- case IR_TEXP:
- opcode = OPCODE_TXP;
- break;
- case IR_TEXP_SH:
- opcode = OPCODE_TXP;
- shadow = GL_TRUE;
- break;
- default:
- _mesa_problem(NULL, "Bad IR TEX code");
- return NULL;
- }
-
- if (n->Children[0]->Opcode == IR_ELEMENT) {
- /* array is the sampler (a uniform which'll indicate the texture unit) */
- assert(n->Children[0]->Children[0]->Store);
- assert(n->Children[0]->Children[0]->Store->File == PROGRAM_SAMPLER);
-
- emit(emitInfo, n->Children[0]);
-
- n->Children[0]->Var = n->Children[0]->Children[0]->Var;
- } else {
- /* this is the sampler (a uniform which'll indicate the texture unit) */
- assert(n->Children[0]->Store);
- assert(n->Children[0]->Store->File == PROGRAM_SAMPLER);
- }
-
- /* emit code for the texcoord operand */
- (void) emit(emitInfo, n->Children[1]);
-
- /* alloc storage for result of texture fetch */
- if (!alloc_node_storage(emitInfo, n, 4))
- return NULL;
-
- /* emit TEX instruction; Child[1] is the texcoord */
- inst = emit_instruction(emitInfo,
- opcode,
- n->Store,
- n->Children[1]->Store,
- NULL,
- NULL);
- if (!inst) {
- return NULL;
- }
-
- inst->TexShadow = shadow;
-
- /* Store->Index is the uniform/sampler index */
- assert(n->Children[0]->Store->Index >= 0);
- inst->TexSrcUnit = n->Children[0]->Store->Index;
- inst->TexSrcTarget = n->Children[0]->Store->TexTarget;
-
- /* mark the sampler as being used */
- _mesa_use_uniform(emitInfo->prog->Parameters,
- (char *) n->Children[0]->Var->a_name);
-
- return inst;
-}
-
-
-/**
- * Assignment/copy
- */
-static struct prog_instruction *
-emit_copy(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst;
-
- assert(n->Opcode == IR_COPY);
-
- /* lhs */
- emit(emitInfo, n->Children[0]);
- if (!n->Children[0]->Store || n->Children[0]->Store->Index < 0) {
- /* an error should have been already recorded */
- return NULL;
- }
-
- /* rhs */
- assert(n->Children[1]);
- inst = emit(emitInfo, n->Children[1]);
-
- if (!n->Children[1]->Store || n->Children[1]->Store->Index < 0) {
- if (!emitInfo->log->text && !emitInfo->UnresolvedFunctions) {
- /* XXX this error should have been caught in slang_codegen.c */
- slang_info_log_error(emitInfo->log, "invalid assignment");
- }
- return NULL;
- }
-
- assert(n->Children[1]->Store->Index >= 0);
-
- /*assert(n->Children[0]->Store->Size == n->Children[1]->Store->Size);*/
-
- n->Store = n->Children[0]->Store;
-
- if (n->Store->File == PROGRAM_SAMPLER) {
- /* no code generated for sampler assignments,
- * just copy the sampler index/target at compile time.
- */
- n->Store->Index = n->Children[1]->Store->Index;
- n->Store->TexTarget = n->Children[1]->Store->TexTarget;
- return NULL;
- }
-
-#if PEEPHOLE_OPTIMIZATIONS
- if (inst &&
- (n->Children[1]->Opcode != IR_SWIZZLE) &&
- _slang_is_temp(emitInfo->vt, n->Children[1]->Store) &&
- (inst->DstReg.File == n->Children[1]->Store->File) &&
- (inst->DstReg.Index == n->Children[1]->Store->Index) &&
- !n->Children[0]->Store->IsIndirect &&
- n->Children[0]->Store->Size <= 4) {
- /* Peephole optimization:
- * The Right-Hand-Side has its results in a temporary place.
- * Modify the RHS (and the prev instruction) to store its results
- * in the destination specified by n->Children[0].
- * Then, this MOVE is a no-op.
- * Ex:
- * MUL tmp, x, y;
- * MOV a, tmp;
- * becomes:
- * MUL a, x, y;
- */
-
- /* fixup the previous instruction (which stored the RHS result) */
- assert(n->Children[0]->Store->Index >= 0);
- storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store);
- return inst;
- }
- else
-#endif
- {
- if (n->Children[0]->Store->Size > 4) {
- /* move matrix/struct etc (block of registers) */
- slang_ir_storage dstStore = *n->Children[0]->Store;
- slang_ir_storage srcStore = *n->Children[1]->Store;
- GLint size = srcStore.Size;
- ASSERT(n->Children[1]->Store->Swizzle == SWIZZLE_NOOP);
- dstStore.Size = 4;
- srcStore.Size = 4;
- while (size >= 4) {
- inst = emit_instruction(emitInfo, OPCODE_MOV,
- &dstStore,
- &srcStore,
- NULL,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, "IR_COPY block");
- srcStore.Index++;
- dstStore.Index++;
- size -= 4;
- }
- }
- else {
- /* single register move */
- char *srcAnnot, *dstAnnot;
- assert(n->Children[0]->Store->Index >= 0);
- inst = emit_instruction(emitInfo, OPCODE_MOV,
- n->Children[0]->Store, /* dest */
- n->Children[1]->Store,
- NULL,
- NULL);
- if (!inst) {
- return NULL;
- }
- dstAnnot = storage_annotation(n->Children[0], emitInfo->prog);
- srcAnnot = storage_annotation(n->Children[1], emitInfo->prog);
- inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
- srcAnnot, NULL, NULL);
- }
- free_node_storage(emitInfo->vt, n->Children[1]);
- return inst;
- }
-}
-
-
-/**
- * An IR_COND node wraps a boolean expression which is used by an
- * IF or WHILE test. This is where we'll set condition codes, if needed.
- */
-static struct prog_instruction *
-emit_cond(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst;
-
- assert(n->Opcode == IR_COND);
-
- if (!n->Children[0])
- return NULL;
-
- /* emit code for the expression */
- inst = emit(emitInfo, n->Children[0]);
-
- if (!n->Children[0]->Store) {
- /* error recovery */
- return NULL;
- }
-
- assert(n->Children[0]->Store);
- /*assert(n->Children[0]->Store->Size == 1);*/
-
- if (emitInfo->EmitCondCodes) {
- if (inst &&
- n->Children[0]->Store &&
- inst->DstReg.File == n->Children[0]->Store->File &&
- inst->DstReg.Index == n->Children[0]->Store->Index) {
- /* The previous instruction wrote to the register who's value
- * we're testing. Just fix that instruction so that the
- * condition codes are computed.
- */
- inst->CondUpdate = GL_TRUE;
- n->Store = n->Children[0]->Store;
- return inst;
- }
- else {
- /* This'll happen for things like "if (i) ..." where no code
- * is normally generated for the expression "i".
- * Generate a move instruction just to set condition codes.
- */
- if (!alloc_node_storage(emitInfo, n, 1))
- return NULL;
- inst = emit_instruction(emitInfo, OPCODE_MOV,
- n->Store, /* dest */
- n->Children[0]->Store,
- NULL,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst->CondUpdate = GL_TRUE;
- inst_comment(inst, "COND expr");
- _slang_free_temp(emitInfo->vt, n->Store);
- return inst;
- }
- }
- else {
- /* No-op: the boolean result of the expression is in a regular reg */
- n->Store = n->Children[0]->Store;
- return inst;
- }
-}
-
-
-/**
- * Logical-NOT
- */
-static struct prog_instruction *
-emit_not(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- static const struct {
- gl_inst_opcode op, opNot;
- } operators[] = {
- { OPCODE_SLT, OPCODE_SGE },
- { OPCODE_SLE, OPCODE_SGT },
- { OPCODE_SGT, OPCODE_SLE },
- { OPCODE_SGE, OPCODE_SLT },
- { OPCODE_SEQ, OPCODE_SNE },
- { OPCODE_SNE, OPCODE_SEQ },
- { 0, 0 }
- };
- struct prog_instruction *inst;
- slang_ir_storage zero;
- GLuint i;
-
- /* child expr */
- inst = emit(emitInfo, n->Children[0]);
-
-#if PEEPHOLE_OPTIMIZATIONS
- if (inst) {
- /* if the prev instruction was a comparison instruction, invert it */
- for (i = 0; operators[i].op; i++) {
- if (inst->Opcode == operators[i].op) {
- inst->Opcode = operators[i].opNot;
- n->Store = n->Children[0]->Store;
- return inst;
- }
- }
- }
-#endif
-
- /* else, invert using SEQ (v = v == 0) */
- if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
- return NULL;
-
- constant_to_storage(emitInfo, 0.0, &zero);
- inst = emit_instruction(emitInfo,
- OPCODE_SEQ,
- n->Store,
- n->Children[0]->Store,
- &zero,
- NULL);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, "NOT");
-
- free_node_storage(emitInfo->vt, n->Children[0]);
-
- return inst;
-}
-
-
-static struct prog_instruction *
-emit_if(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct gl_program *prog = emitInfo->prog;
- GLuint ifInstLoc, elseInstLoc = 0;
- GLuint condWritemask = 0;
-
- /* emit condition expression code */
- {
- struct prog_instruction *inst;
- inst = emit(emitInfo, n->Children[0]);
- if (emitInfo->EmitCondCodes) {
- if (!inst) {
- /* error recovery */
- return NULL;
- }
- condWritemask = inst->DstReg.WriteMask;
- }
- }
-
- if (!n->Children[0]->Store)
- return NULL;
-
-#if 0
- assert(n->Children[0]->Store->Size == 1); /* a bool! */
-#endif
-
- ifInstLoc = prog->NumInstructions;
- if (emitInfo->EmitHighLevelInstructions) {
- if (emitInfo->EmitCondCodes) {
- /* IF condcode THEN ... */
- struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_IF);
- if (!ifInst) {
- return NULL;
- }
- ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */
- /* only test the cond code (1 of 4) that was updated by the
- * previous instruction.
- */
- ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
- }
- else {
- struct prog_instruction *inst;
-
- /* IF src[0] THEN ... */
- inst = emit_instruction(emitInfo, OPCODE_IF,
- NULL, /* dst */
- n->Children[0]->Store, /* op0 */
- NULL,
- NULL);
- if (!inst) {
- return NULL;
- }
- }
- }
- else {
- /* conditional jump to else, or endif */
- struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_BRA);
- if (!ifInst) {
- return NULL;
- }
- ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */
- inst_comment(ifInst, "if zero");
- ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
- }
-
- /* if body */
- emit(emitInfo, n->Children[1]);
-
- if (n->Children[2]) {
- /* have else body */
- elseInstLoc = prog->NumInstructions;
- if (emitInfo->EmitHighLevelInstructions) {
- struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ELSE);
- if (!inst) {
- return NULL;
- }
- prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions - 1;
- }
- else {
- /* jump to endif instruction */
- struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BRA);
- if (!inst) {
- return NULL;
- }
- inst_comment(inst, "else");
- inst->DstReg.CondMask = COND_TR; /* always branch */
- prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions;
- }
- emit(emitInfo, n->Children[2]);
- }
- else {
- /* no else body */
- prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions;
- }
-
- if (emitInfo->EmitHighLevelInstructions) {
- struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ENDIF);
- if (!inst) {
- return NULL;
- }
- }
-
- if (elseInstLoc) {
- /* point ELSE instruction BranchTarget at ENDIF */
- if (emitInfo->EmitHighLevelInstructions) {
- prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions - 1;
- }
- else {
- prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions;
- }
- }
- return NULL;
-}
-
-
-static struct prog_instruction *
-emit_loop(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct gl_program *prog = emitInfo->prog;
- struct prog_instruction *endInst;
- GLuint beginInstLoc, tailInstLoc, endInstLoc;
- slang_ir_node *ir;
-
- /* emit OPCODE_BGNLOOP */
- beginInstLoc = prog->NumInstructions;
- if (emitInfo->EmitHighLevelInstructions) {
- struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BGNLOOP);
- if (!inst) {
- return NULL;
- }
- }
-
- /* body */
- emit(emitInfo, n->Children[0]);
-
- /* tail */
- tailInstLoc = prog->NumInstructions;
- if (n->Children[1]) {
- if (emitInfo->EmitComments)
- emit_comment(emitInfo, "Loop tail code:");
- emit(emitInfo, n->Children[1]);
- }
-
- endInstLoc = prog->NumInstructions;
- if (emitInfo->EmitHighLevelInstructions) {
- /* emit OPCODE_ENDLOOP */
- endInst = new_instruction(emitInfo, OPCODE_ENDLOOP);
- if (!endInst) {
- return NULL;
- }
- }
- else {
- /* emit unconditional BRA-nch */
- endInst = new_instruction(emitInfo, OPCODE_BRA);
- if (!endInst) {
- return NULL;
- }
- endInst->DstReg.CondMask = COND_TR; /* always true */
- }
- /* ENDLOOP's BranchTarget points to the BGNLOOP inst */
- endInst->BranchTarget = beginInstLoc;
-
- if (emitInfo->EmitHighLevelInstructions) {
- /* BGNLOOP's BranchTarget points to the ENDLOOP inst */
- prog->Instructions[beginInstLoc].BranchTarget = prog->NumInstructions -1;
- }
-
- /* Done emitting loop code. Now walk over the loop's linked list of
- * BREAK and CONT nodes, filling in their BranchTarget fields (which
- * will point to the corresponding ENDLOOP instruction.
- */
- for (ir = n->List; ir; ir = ir->List) {
- struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
- assert(inst->BranchTarget < 0);
- if (ir->Opcode == IR_BREAK ||
- ir->Opcode == IR_BREAK_IF_TRUE) {
- assert(inst->Opcode == OPCODE_BRK ||
- inst->Opcode == OPCODE_BRA);
- /* go to instruction at end of loop */
- if (emitInfo->EmitHighLevelInstructions) {
- inst->BranchTarget = endInstLoc;
- }
- else {
- inst->BranchTarget = endInstLoc + 1;
- }
- }
- else {
- assert(ir->Opcode == IR_CONT ||
- ir->Opcode == IR_CONT_IF_TRUE);
- assert(inst->Opcode == OPCODE_CONT ||
- inst->Opcode == OPCODE_BRA);
- /* go to instruction at tail of loop */
- inst->BranchTarget = endInstLoc;
- }
- }
- return NULL;
-}
-
-
-/**
- * Unconditional "continue" or "break" statement.
- * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted.
- */
-static struct prog_instruction *
-emit_cont_break(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- gl_inst_opcode opcode;
- struct prog_instruction *inst;
-
- if (n->Opcode == IR_CONT) {
- /* we need to execute the loop's tail code before doing CONT */
- assert(n->Parent);
- assert(n->Parent->Opcode == IR_LOOP);
- if (n->Parent->Children[1]) {
- /* emit tail code */
- if (emitInfo->EmitComments) {
- emit_comment(emitInfo, "continue - tail code:");
- }
- emit(emitInfo, n->Parent->Children[1]);
- }
- }
-
- /* opcode selection */
- if (emitInfo->EmitHighLevelInstructions) {
- opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK;
- }
- else {
- opcode = OPCODE_BRA;
- }
- n->InstLocation = emitInfo->prog->NumInstructions;
- inst = new_instruction(emitInfo, opcode);
- if (inst) {
- inst->DstReg.CondMask = COND_TR; /* always true */
- }
- return inst;
-}
-
-
-/**
- * Conditional "continue" or "break" statement.
- * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted.
- */
-static struct prog_instruction *
-emit_cont_break_if_true(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst;
-
- assert(n->Opcode == IR_CONT_IF_TRUE ||
- n->Opcode == IR_BREAK_IF_TRUE);
-
- /* evaluate condition expr, setting cond codes */
- inst = emit(emitInfo, n->Children[0]);
- if (emitInfo->EmitCondCodes) {
- assert(inst);
- inst->CondUpdate = GL_TRUE;
- }
-
- n->InstLocation = emitInfo->prog->NumInstructions;
-
- /* opcode selection */
- if (emitInfo->EmitHighLevelInstructions) {
- const gl_inst_opcode opcode
- = (n->Opcode == IR_CONT_IF_TRUE) ? OPCODE_CONT : OPCODE_BRK;
- if (emitInfo->EmitCondCodes) {
- /* Get the writemask from the previous instruction which set
- * the condcodes. Use that writemask as the CondSwizzle.
- */
- const GLuint condWritemask = inst->DstReg.WriteMask;
- inst = new_instruction(emitInfo, opcode);
- if (inst) {
- inst->DstReg.CondMask = COND_NE;
- inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
- }
- return inst;
- }
- else {
- /* IF reg
- * BRK/CONT;
- * ENDIF
- */
- GLint ifInstLoc;
- ifInstLoc = emitInfo->prog->NumInstructions;
- inst = emit_instruction(emitInfo, OPCODE_IF,
- NULL, /* dest */
- n->Children[0]->Store,
- NULL,
- NULL);
- if (!inst) {
- return NULL;
- }
- n->InstLocation = emitInfo->prog->NumInstructions;
-
- inst = new_instruction(emitInfo, opcode);
- if (!inst) {
- return NULL;
- }
- inst = new_instruction(emitInfo, OPCODE_ENDIF);
- if (!inst) {
- return NULL;
- }
-
- emitInfo->prog->Instructions[ifInstLoc].BranchTarget
- = emitInfo->prog->NumInstructions - 1;
- return inst;
- }
- }
- else {
- const GLuint condWritemask = inst->DstReg.WriteMask;
- assert(emitInfo->EmitCondCodes);
- inst = new_instruction(emitInfo, OPCODE_BRA);
- if (inst) {
- inst->DstReg.CondMask = COND_NE;
- inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
- }
- return inst;
- }
-}
-
-
-/**
- * Return the size of a swizzle mask given that some swizzle components
- * may be NIL/undefined. For example:
- * swizzle_size(".zzxx") = 4
- * swizzle_size(".xy??") = 2
- * swizzle_size(".w???") = 1
- */
-static GLuint
-swizzle_size(GLuint swizzle)
-{
- GLuint i;
- for (i = 0; i < 4; i++) {
- if (GET_SWZ(swizzle, i) == SWIZZLE_NIL)
- return i;
- }
- return 4;
-}
-
-
-static struct prog_instruction *
-emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst;
-
- inst = emit(emitInfo, n->Children[0]);
-
- if (!n->Store->Parent) {
- /* this covers a case such as "(b ? p : q).x" */
- n->Store->Parent = n->Children[0]->Store;
- assert(n->Store->Parent);
- }
-
- {
- const GLuint swizzle = n->Store->Swizzle;
- /* new storage is parent storage with updated Swizzle + Size fields */
- _slang_copy_ir_storage(n->Store, n->Store->Parent);
- /* Apply this node's swizzle to parent's storage */
- n->Store->Swizzle = _slang_swizzle_swizzle(n->Store->Swizzle, swizzle);
- /* Update size */
- n->Store->Size = swizzle_size(n->Store->Swizzle);
- }
-
- assert(!n->Store->Parent);
- assert(n->Store->Index >= 0);
-
- return inst;
-}
-
-
-/**
- * Dereference array element: element == array[index]
- * This basically involves emitting code for computing the array index
- * and updating the node/element's storage info.
- */
-static struct prog_instruction *
-emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- slang_ir_storage *arrayStore, *indexStore;
- const int elemSize = n->Store->Size; /* number of floats */
- const GLint elemSizeVec = (elemSize + 3) / 4; /* number of vec4 */
- struct prog_instruction *inst;
-
- assert(n->Opcode == IR_ELEMENT);
- assert(elemSize > 0);
-
- /* special case for built-in state variables, like light state */
- {
- slang_ir_storage *root = n->Store;
- assert(!root->Parent);
- while (root->Parent)
- root = root->Parent;
-
- if (root->File == PROGRAM_STATE_VAR) {
- GLboolean direct;
- GLint index =
- _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
- if (index < 0) {
- /* error */
- return NULL;
- }
- if (direct) {
- n->Store->Index = index;
- return NULL; /* all done */
- }
- }
- }
-
- /* do codegen for array itself */
- emit(emitInfo, n->Children[0]);
- arrayStore = n->Children[0]->Store;
-
- /* The initial array element storage is the array's storage,
- * then modified below.
- */
- _slang_copy_ir_storage(n->Store, arrayStore);
-
-
- if (n->Children[1]->Opcode == IR_FLOAT) {
- /* Constant array index */
- const GLint element = (GLint) n->Children[1]->Value[0];
-
- /* this element's storage is the array's storage, plus constant offset */
- n->Store->Index += elemSizeVec * element;
- }
- else {
- /* Variable array index */
-
- /* do codegen for array index expression */
- emit(emitInfo, n->Children[1]);
- indexStore = n->Children[1]->Store;
-
- if (indexStore->IsIndirect) {
- /* need to put the array index into a temporary since we can't
- * directly support a[b[i]] constructs.
- */
-
-
- /*indexStore = tempstore();*/
- }
-
-
- if (elemSize > 4) {
- /* need to multiply array index by array element size */
- struct prog_instruction *inst;
- slang_ir_storage *indexTemp;
- slang_ir_storage elemSizeStore;
-
- /* allocate 1 float indexTemp */
- indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
- _slang_alloc_temp(emitInfo->vt, indexTemp);
-
- /* allocate a constant containing the element size */
- constant_to_storage(emitInfo, (float) elemSizeVec, &elemSizeStore);
-
- /* multiply array index by element size */
- inst = emit_instruction(emitInfo,
- OPCODE_MUL,
- indexTemp, /* dest */
- indexStore, /* the index */
- &elemSizeStore,
- NULL);
- if (!inst) {
- return NULL;
- }
-
- indexStore = indexTemp;
- }
-
- if (arrayStore->IsIndirect) {
- /* ex: in a[i][j], a[i] (the arrayStore) is indirect */
- /* Need to add indexStore to arrayStore->Indirect store */
- slang_ir_storage indirectArray;
- slang_ir_storage *indexTemp;
-
- _slang_init_ir_storage(&indirectArray,
- arrayStore->IndirectFile,
- arrayStore->IndirectIndex,
- 1,
- arrayStore->IndirectSwizzle);
-
- /* allocate 1 float indexTemp */
- indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
- _slang_alloc_temp(emitInfo->vt, indexTemp);
-
- inst = emit_instruction(emitInfo,
- OPCODE_ADD,
- indexTemp, /* dest */
- indexStore, /* the index */
- &indirectArray, /* indirect array base */
- NULL);
- if (!inst) {
- return NULL;
- }
-
- indexStore = indexTemp;
- }
-
- /* update the array element storage info */
- n->Store->IsIndirect = GL_TRUE;
- n->Store->IndirectFile = indexStore->File;
- n->Store->IndirectIndex = indexStore->Index;
- n->Store->IndirectSwizzle = indexStore->Swizzle;
- }
-
- n->Store->Size = elemSize;
- n->Store->Swizzle = _slang_var_swizzle(elemSize, 0);
-
- return NULL; /* no instruction */
-}
-
-
-/**
- * Resolve storage for accessing a structure field.
- */
-static struct prog_instruction *
-emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- slang_ir_storage *root = n->Store;
- GLint fieldOffset, fieldSize;
-
- assert(n->Opcode == IR_FIELD);
-
- assert(!root->Parent);
- while (root->Parent)
- root = root->Parent;
-
- /* If this is the field of a state var, allocate constant/uniform
- * storage for it now if we haven't already.
- * Note that we allocate storage (uniform/constant slots) for state
- * variables here rather than at declaration time so we only allocate
- * space for the ones that we actually use!
- */
- if (root->File == PROGRAM_STATE_VAR) {
- GLboolean direct;
- GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
- if (index < 0) {
- slang_info_log_error(emitInfo->log, "Error parsing state variable");
- return NULL;
- }
- if (direct) {
- root->Index = index;
- return NULL; /* all done */
- }
- }
-
- /* do codegen for struct */
- emit(emitInfo, n->Children[0]);
- assert(n->Children[0]->Store->Index >= 0);
-
-
- fieldOffset = n->Store->Index;
- fieldSize = n->Store->Size;
-
- _slang_copy_ir_storage(n->Store, n->Children[0]->Store);
-
- n->Store->Index = n->Children[0]->Store->Index + fieldOffset / 4;
- n->Store->Size = fieldSize;
-
- switch (fieldSize) {
- case 1:
- {
- GLint swz = fieldOffset % 4;
- n->Store->Swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz);
- }
- break;
- case 2:
- n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
- SWIZZLE_NIL, SWIZZLE_NIL);
- break;
- case 3:
- n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
- SWIZZLE_Z, SWIZZLE_NIL);
- break;
- default:
- n->Store->Swizzle = SWIZZLE_XYZW;
- }
-
- assert(n->Store->Index >= 0);
-
- return NULL; /* no instruction */
-}
-
-
-/**
- * Emit code for a variable declaration.
- * This usually doesn't result in any code generation, but just
- * memory allocation.
- */
-static struct prog_instruction *
-emit_var_decl(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- assert(n->Store);
- assert(n->Store->File != PROGRAM_UNDEFINED);
- assert(n->Store->Size > 0);
- /*assert(n->Store->Index < 0);*/
-
- if (!n->Var || n->Var->isTemp) {
- /* a nameless/temporary variable, will be freed after first use */
- /*NEW*/
- if (n->Store->Index < 0 && !_slang_alloc_temp(emitInfo->vt, n->Store)) {
- slang_info_log_error(emitInfo->log,
- "Ran out of registers, too many temporaries");
- return NULL;
- }
- }
- else {
- /* a regular variable */
- _slang_add_variable(emitInfo->vt, n->Var);
- if (!_slang_alloc_var(emitInfo->vt, n->Store)) {
- slang_info_log_error(emitInfo->log,
- "Ran out of registers, too many variables");
- return NULL;
- }
- /*
- printf("IR_VAR_DECL %s %d store %p\n",
- (char*) n->Var->a_name, n->Store->Index, (void*) n->Store);
- */
- assert(n->Var->store == n->Store);
- }
- if (emitInfo->EmitComments) {
- /* emit NOP with comment describing the variable's storage location */
- char s[1000];
- _mesa_snprintf(s, sizeof(s), "TEMP[%d]%s = variable %s (size %d)",
- n->Store->Index,
- _mesa_swizzle_string(n->Store->Swizzle, 0, GL_FALSE),
- (n->Var ? (char *) n->Var->a_name : "anonymous"),
- n->Store->Size);
- emit_comment(emitInfo, s);
- }
- return NULL;
-}
-
-
-/**
- * Emit code for a reference to a variable.
- * Actually, no code is generated but we may do some memory allocation.
- * In particular, state vars (uniforms) are allocated on an as-needed basis.
- */
-static struct prog_instruction *
-emit_var_ref(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- assert(n->Store);
- assert(n->Store->File != PROGRAM_UNDEFINED);
-
- if (n->Store->File == PROGRAM_STATE_VAR && n->Store->Index < 0) {
- GLboolean direct;
- GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
- if (index < 0) {
- /* error */
- char s[100];
- /* XXX isn't this really an out of memory/resources error? */
- _mesa_snprintf(s, sizeof(s), "Undefined variable '%s'",
- (char *) n->Var->a_name);
- slang_info_log_error(emitInfo->log, s);
- return NULL;
- }
-
- n->Store->Index = index;
- }
- else if (n->Store->File == PROGRAM_UNIFORM ||
- n->Store->File == PROGRAM_SAMPLER) {
- /* mark var as used */
- _mesa_use_uniform(emitInfo->prog->Parameters, (char *) n->Var->a_name);
- }
- else if (n->Store->File == PROGRAM_INPUT) {
- assert(n->Store->Index >= 0);
- /* geometry shaders have the input index in the second
- * index */
- if (emitInfo->prog->Target == MESA_GEOMETRY_PROGRAM &&
- n->Store->Is2D) {
- emitInfo->prog->InputsRead |= (1 << n->Store->Index2);
- } else
- emitInfo->prog->InputsRead |= (1 << n->Store->Index);
- }
-
- if (n->Store->Index < 0) {
- /* probably ran out of registers */
- return NULL;
- }
- assert(n->Store->Size > 0);
-
- return NULL;
-}
-
-
-static struct prog_instruction *
-emit(slang_emit_info *emitInfo, slang_ir_node *n)
-{
- struct prog_instruction *inst;
- if (!n)
- return NULL;
-
- if (emitInfo->log->error_flag) {
- return NULL;
- }
-
- if (n->Comment) {
- inst = new_instruction(emitInfo, OPCODE_NOP);
- if (inst) {
- inst->Comment = _mesa_strdup(n->Comment);
- }
- inst = NULL;
- }
-
- switch (n->Opcode) {
- case IR_SEQ:
- /* sequence of two sub-trees */
- assert(n->Children[0]);
- assert(n->Children[1]);
- emit(emitInfo, n->Children[0]);
- if (emitInfo->log->error_flag)
- return NULL;
- inst = emit(emitInfo, n->Children[1]);
-#if 0
- assert(!n->Store);
-#endif
- if (n->Children[1]->Store)
- n->Store = n->Children[1]->Store;
- else
- n->Store = n->Children[0]->Store;
- return inst;
-
- case IR_SCOPE:
- /* new variable scope */
- _slang_push_var_table(emitInfo->vt);
- inst = emit(emitInfo, n->Children[0]);
- _slang_pop_var_table(emitInfo->vt);
- n->Store = n->Children[0]->Store;
- return inst;
-
- case IR_VAR_DECL:
- /* Variable declaration - allocate a register for it */
- inst = emit_var_decl(emitInfo, n);
- return inst;
-
- case IR_VAR:
- /* Reference to a variable
- * Storage should have already been resolved/allocated.
- */
- return emit_var_ref(emitInfo, n);
-
- case IR_ELEMENT:
- return emit_array_element(emitInfo, n);
- case IR_FIELD:
- return emit_struct_field(emitInfo, n);
- case IR_SWIZZLE:
- return emit_swizzle(emitInfo, n);
-
- /* Simple arithmetic */
- /* unary */
- case IR_MOVE:
- case IR_RSQ:
- case IR_RCP:
- case IR_FLOOR:
- case IR_FRAC:
- case IR_F_TO_I:
- case IR_I_TO_F:
- case IR_ABS:
- case IR_SIN:
- case IR_COS:
- case IR_DDX:
- case IR_DDY:
- case IR_EXP:
- case IR_EXP2:
- case IR_LOG2:
- case IR_NOISE1:
- case IR_NOISE2:
- case IR_NOISE3:
- case IR_NOISE4:
- case IR_NRM4:
- case IR_NRM3:
- /* binary */
- case IR_ADD:
- case IR_SUB:
- case IR_MUL:
- case IR_DOT4:
- case IR_DOT3:
- case IR_DOT2:
- case IR_CROSS:
- case IR_MIN:
- case IR_MAX:
- case IR_SEQUAL:
- case IR_SNEQUAL:
- case IR_SGE:
- case IR_SGT:
- case IR_SLE:
- case IR_SLT:
- case IR_POW:
- /* trinary operators */
- case IR_LRP:
- case IR_CMP:
- return emit_arith(emitInfo, n);
-
- case IR_EQUAL:
- case IR_NOTEQUAL:
- return emit_compare(emitInfo, n);
-
- case IR_CLAMP:
- return emit_clamp(emitInfo, n);
- case IR_TEX:
- case IR_TEXB:
- case IR_TEXP:
- case IR_TEX_SH:
- case IR_TEXB_SH:
- case IR_TEXP_SH:
- return emit_tex(emitInfo, n);
- case IR_NEG:
- return emit_negation(emitInfo, n);
- case IR_FLOAT:
- /* find storage location for this float constant */
- n->Store->Index = _mesa_add_unnamed_constant(emitInfo->prog->Parameters,
- n->Value,
- n->Store->Size,
- &n->Store->Swizzle);
- if (n->Store->Index < 0) {
- slang_info_log_error(emitInfo->log, "Ran out of space for constants");
- return NULL;
- }
- return NULL;
-
- case IR_COPY:
- return emit_copy(emitInfo, n);
-
- case IR_COND:
- return emit_cond(emitInfo, n);
-
- case IR_NOT:
- return emit_not(emitInfo, n);
-
- case IR_LABEL:
- return emit_label(emitInfo, n);
-
- case IR_KILL:
- return emit_kill(emitInfo);
-
- case IR_CALL:
- /* new variable scope for subroutines/function calls */
- _slang_push_var_table(emitInfo->vt);
- inst = emit_fcall(emitInfo, n);
- _slang_pop_var_table(emitInfo->vt);
- return inst;
-
- case IR_IF:
- return emit_if(emitInfo, n);
-
- case IR_LOOP:
- return emit_loop(emitInfo, n);
- case IR_BREAK_IF_TRUE:
- case IR_CONT_IF_TRUE:
- return emit_cont_break_if_true(emitInfo, n);
- case IR_BREAK:
- /* fall-through */
- case IR_CONT:
- return emit_cont_break(emitInfo, n);
-
- case IR_BEGIN_SUB:
- return new_instruction(emitInfo, OPCODE_BGNSUB);
- case IR_END_SUB:
- return new_instruction(emitInfo, OPCODE_ENDSUB);
- case IR_RETURN:
- return emit_return(emitInfo, n);
-
- case IR_NOP:
- return NULL;
-
- case IR_EMIT_VERTEX:
- return new_instruction(emitInfo, OPCODE_EMIT_VERTEX);
- case IR_END_PRIMITIVE:
- return new_instruction(emitInfo, OPCODE_END_PRIMITIVE);
-
- default:
- _mesa_problem(NULL, "Unexpected IR opcode in emit()\n");
- }
- return NULL;
-}
-
-
-/**
- * After code generation, any subroutines will be in separate program
- * objects. This function appends all the subroutines onto the main
- * program and resolves the linking of all the branch/call instructions.
- * XXX this logic should really be part of the linking process...
- */
-static void
-_slang_resolve_subroutines(slang_emit_info *emitInfo)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl_program *mainP = emitInfo->prog;
- GLuint *subroutineLoc, i, total;
-
- subroutineLoc
- = (GLuint *) malloc(emitInfo->NumSubroutines * sizeof(GLuint));
-
- /* total number of instructions */
- total = mainP->NumInstructions;
- for (i = 0; i < emitInfo->NumSubroutines; i++) {
- subroutineLoc[i] = total;
- total += emitInfo->Subroutines[i]->NumInstructions;
- }
-
- /* adjust BranchTargets within the functions */
- for (i = 0; i < emitInfo->NumSubroutines; i++) {
- struct gl_program *sub = emitInfo->Subroutines[i];
- GLuint j;
- for (j = 0; j < sub->NumInstructions; j++) {
- struct prog_instruction *inst = sub->Instructions + j;
- if (inst->Opcode != OPCODE_CAL && inst->BranchTarget >= 0) {
- inst->BranchTarget += subroutineLoc[i];
- }
- }
- }
-
- /* append subroutines' instructions after main's instructions */
- mainP->Instructions = _mesa_realloc_instructions(mainP->Instructions,
- mainP->NumInstructions,
- total);
- mainP->NumInstructions = total;
- for (i = 0; i < emitInfo->NumSubroutines; i++) {
- struct gl_program *sub = emitInfo->Subroutines[i];
- _mesa_copy_instructions(mainP->Instructions + subroutineLoc[i],
- sub->Instructions,
- sub->NumInstructions);
- /* delete subroutine code */
- sub->Parameters = NULL; /* prevent double-free */
- _mesa_reference_program(ctx, &emitInfo->Subroutines[i], NULL);
- }
-
- /* free subroutine list */
- if (emitInfo->Subroutines) {
- free(emitInfo->Subroutines);
- emitInfo->Subroutines = NULL;
- }
- emitInfo->NumSubroutines = 0;
-
- /* Examine CAL instructions.
- * At this point, the BranchTarget field of the CAL instruction is
- * the number/id of the subroutine to call (an index into the
- * emitInfo->Subroutines list).
- * Translate that into an actual instruction location now.
- */
- for (i = 0; i < mainP->NumInstructions; i++) {
- struct prog_instruction *inst = mainP->Instructions + i;
- if (inst->Opcode == OPCODE_CAL) {
- const GLuint f = inst->BranchTarget;
- inst->BranchTarget = subroutineLoc[f];
- }
- }
-
- free(subroutineLoc);
-}
-
-
-
-/**
- * Convert the IR tree into GPU instructions.
- * \param n root of IR tree
- * \param vt variable table
- * \param prog program to put GPU instructions into
- * \param pragmas controls codegen options
- * \param withEnd if true, emit END opcode at end
- * \param log log for emitting errors/warnings/info
- */
-GLboolean
-_slang_emit_code(slang_ir_node *n, slang_var_table *vt,
- struct gl_program *prog,
- const struct gl_sl_pragmas *pragmas,
- GLboolean withEnd,
- slang_info_log *log)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLboolean success;
- slang_emit_info emitInfo;
- GLuint maxUniforms;
-
- emitInfo.log = log;
- emitInfo.vt = vt;
- emitInfo.prog = prog;
- emitInfo.Subroutines = NULL;
- emitInfo.NumSubroutines = 0;
- emitInfo.MaxInstructions = prog->NumInstructions;
-
- emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions;
- emitInfo.EmitCondCodes = ctx->Shader.EmitCondCodes;
- emitInfo.EmitComments = ctx->Shader.EmitComments || pragmas->Debug;
- emitInfo.EmitBeginEndSub = GL_TRUE;
-
- if (!emitInfo.EmitCondCodes) {
- emitInfo.EmitHighLevelInstructions = GL_TRUE;
- }
-
- /* Check uniform/constant limits */
- if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
- maxUniforms = ctx->Const.FragmentProgram.MaxUniformComponents / 4;
- }
- else if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
- maxUniforms = ctx->Const.VertexProgram.MaxUniformComponents / 4;
- } else {
- assert(prog->Target == MESA_GEOMETRY_PROGRAM);
- maxUniforms = ctx->Const.GeometryProgram.MaxUniformComponents / 4;
- }
- if (prog->Parameters->NumParameters > maxUniforms) {
- slang_info_log_error(log, "Constant/uniform register limit exceeded "
- "(max=%u vec4)", maxUniforms);
-
- return GL_FALSE;
- }
-
- (void) emit(&emitInfo, n);
-
- /* finish up by adding the END opcode to program */
- if (withEnd) {
- struct prog_instruction *inst;
- inst = new_instruction(&emitInfo, OPCODE_END);
- if (!inst) {
- return GL_FALSE;
- }
- }
-
- _slang_resolve_subroutines(&emitInfo);
-
- success = GL_TRUE;
-
-#if 0
- printf("*********** End emit code (%u inst):\n", prog->NumInstructions);
- _mesa_print_program(prog);
- _mesa_print_program_parameters(ctx,prog);
-#endif
-
- return success;
-}
diff --git a/src/mesa/slang/slang_ir.c b/src/mesa/slang/slang_ir.c
deleted file mode 100644
index 078c9369a89..00000000000
--- a/src/mesa/slang/slang_ir.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 VMware, 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.
- */
-
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "slang_ir.h"
-#include "slang_mem.h"
-#include "program/prog_instruction.h"
-#include "program/prog_print.h"
-
-
-static const slang_ir_info IrInfo[] = {
- /* binary ops */
- { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 },
- { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 },
- { IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 },
- { IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */
- { IR_DOT4, "IR_DOT4", OPCODE_DP4, 1, 2 },
- { IR_DOT3, "IR_DOT3", OPCODE_DP3, 1, 2 },
- { IR_DOT2, "IR_DOT2", OPCODE_DP2, 1, 2 },
- { IR_NRM4, "IR_NRM4", OPCODE_NRM4, 1, 1 },
- { IR_NRM3, "IR_NRM3", OPCODE_NRM3, 1, 1 },
- { IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 },
- { IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 },
- { IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 },
- { IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 },
- { IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */
- { IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 },
- { IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 },
- { IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 },
- { IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 },
- { IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 },
- { IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 },
- { IR_POW, "IR_POW", OPCODE_POW, 1, 2 },
- { IR_EQUAL, "IR_EQUAL", OPCODE_NOP, 1, 2 },
- { IR_NOTEQUAL, "IR_NOTEQUAL", OPCODE_NOP, 1, 2 },
-
- /* unary ops */
- { IR_MOVE, "IR_MOVE", OPCODE_MOV, 4, 1 },
- { IR_I_TO_F, "IR_I_TO_F", OPCODE_MOV, 4, 1 }, /* int[4] to float[4] */
- { IR_F_TO_I, "IR_F_TO_I", OPCODE_TRUNC, 4, 1 },
- { IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 },
- { IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 },
- { IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 },
- { IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 },
- { IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 },
- { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 },
- { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 },
- { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 },
- { IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */
- { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 },
- { IR_DDY, "IR_DDY", OPCODE_DDY, 4, 1 },
- { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 },
- { IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
- { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 },
- { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 },
- { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 },
- { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 },
-
- /* other */
- { IR_CMP, "IR_CMP", OPCODE_CMP, 4, 3 }, /* compare/select */
- { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
- { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
- { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
- { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
- { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
- { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
- { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
- { IR_COPY, "IR_COPY", OPCODE_NOP, 0, 1 },
- { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 },
- { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 },
- { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 },
- { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 },
- { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 },
- { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 },
- { IR_TEX_SH, "IR_TEX_SH", OPCODE_TEX, 4, 1 },
- { IR_TEXB_SH, "IR_TEXB_SH", OPCODE_TXB, 4, 1 },
- { IR_TEXP_SH, "IR_TEXP_SH", OPCODE_TXP, 4, 1 },
- { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */
- { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 },
- { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 },
- { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 },
- { IR_NOP, "IR_NOP", OPCODE_NOP, 0, 0 },
- { IR_EMIT_VERTEX, "IR_EMIT_VERTEX", OPCODE_EMIT_VERTEX, 0, 0 },
- { IR_END_PRIMITIVE, "IR_END_PRIMITIVE", OPCODE_END_PRIMITIVE, 0, 0 },
- { 0, NULL, 0, 0, 0 }
-};
-
-
-const slang_ir_info *
-_slang_ir_info(slang_ir_opcode opcode)
-{
- GLuint i;
- for (i = 0; IrInfo[i].IrName; i++) {
- if (IrInfo[i].IrOpcode == opcode) {
- return IrInfo + i;
- }
- }
- return NULL;
-}
-
-
-void
-_slang_init_ir_storage(slang_ir_storage *st,
- gl_register_file file, GLint index, GLint size,
- GLuint swizzle)
-{
- st->File = file;
- st->Index = index;
- st->Size = size;
- st->Swizzle = swizzle;
- st->Parent = NULL;
- st->IsIndirect = GL_FALSE;
- st->Is2D = GL_FALSE;
- st->Index2 = 0;
-}
-
-
-/**
- * Return a new slang_ir_storage object.
- */
-slang_ir_storage *
-_slang_new_ir_storage(gl_register_file file, GLint index, GLint size)
-{
- slang_ir_storage *st;
- st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
- if (st) {
- st->File = file;
- st->Index = index;
- st->Size = size;
- st->Swizzle = SWIZZLE_NOOP;
- st->Parent = NULL;
- st->IsIndirect = GL_FALSE;
- st->Is2D = GL_FALSE;
- st->Index2 = 0;
- }
- return st;
-}
-
-
-/**
- * Return a new slang_ir_storage object.
- */
-slang_ir_storage *
-_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size,
- GLuint swizzle)
-{
- slang_ir_storage *st;
- st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
- if (st) {
- st->File = file;
- st->Index = index;
- st->Size = size;
- st->Swizzle = swizzle;
- st->Parent = NULL;
- st->IsIndirect = GL_FALSE;
- st->Is2D = GL_FALSE;
- st->Index2 = 0;
- }
- return st;
-}
-
-/**
- * Return a new slang_ir_storage object.
- */
-slang_ir_storage *
-_slang_new_ir_storage_2d(gl_register_file file,
- GLint index, GLint index2,
- GLint size, GLuint swizzle)
-{
- slang_ir_storage *st;
- st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
- if (st) {
- st->File = file;
- st->Index = index;
- st->Size = size;
- st->Swizzle = swizzle;
- st->Parent = NULL;
- st->IsIndirect = GL_FALSE;
- st->Is2D = GL_TRUE;
- st->Index2 = index2;
- }
- return st;
-}
-
-
-
-/**
- * Return a new slang_ir_storage object.
- */
-slang_ir_storage *
-_slang_new_ir_storage_relative(GLint index, GLint size,
- slang_ir_storage *parent)
-{
- slang_ir_storage *st;
- st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
- if (st) {
- st->File = PROGRAM_UNDEFINED;
- st->Index = index;
- st->Size = size;
- st->Swizzle = SWIZZLE_NOOP;
- st->Parent = parent;
- st->IsIndirect = GL_FALSE;
- st->Is2D = GL_FALSE;
- st->Index2 = 0;
- }
- return st;
-}
-
-
-slang_ir_storage *
-_slang_new_ir_storage_indirect(gl_register_file file,
- GLint index,
- GLint size,
- gl_register_file indirectFile,
- GLint indirectIndex,
- GLuint indirectSwizzle)
-{
- slang_ir_storage *st;
- st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
- if (st) {
- st->File = file;
- st->Index = index;
- st->Size = size;
- st->Swizzle = SWIZZLE_NOOP;
- st->IsIndirect = GL_TRUE;
- st->IndirectFile = indirectFile;
- st->IndirectIndex = indirectIndex;
- st->IndirectSwizzle = indirectSwizzle;
- st->Is2D = GL_FALSE;
- st->Index2 = 0;
- }
- return st;
-}
-
-
-/**
- * Allocate IR storage for a texture sampler.
- * \param sampNum the sampler number/index
- * \param texTarget one of TEXTURE_x_INDEX values
- * \param size number of samplers (in case of sampler array)
- */
-slang_ir_storage *
-_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size)
-{
- slang_ir_storage *st;
- assert(texTarget < NUM_TEXTURE_TARGETS);
- st = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, size);
- if (st) {
- st->TexTarget = texTarget;
- }
- return st;
-}
-
-
-
-/* XXX temporary function */
-void
-_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src)
-{
- *dst = *src;
- dst->Parent = NULL;
-}
-
-
-
-static const char *
-_slang_ir_name(slang_ir_opcode opcode)
-{
- return _slang_ir_info(opcode)->IrName;
-}
-
-
-
-#if 0 /* no longer needed with mempool */
-/**
- * Since many IR nodes might point to the same IR storage info, we need
- * to be careful when deleting things.
- * Before deleting an IR tree, traverse it and do refcounting on the
- * IR storage nodes. Use the refcount info during delete to free things
- * properly.
- */
-static void
-_slang_refcount_storage(slang_ir_node *n)
-{
- GLuint i;
- if (!n)
- return;
- if (n->Store)
- n->Store->RefCount++;
- for (i = 0; i < 3; i++)
- _slang_refcount_storage(n->Children[i]);
-}
-#endif
-
-
-static void
-_slang_free_ir(slang_ir_node *n)
-{
- GLuint i;
- if (!n)
- return;
-
-#if 0
- if (n->Store) {
- n->Store->RefCount--;
- if (n->Store->RefCount == 0) {
- _slang_free(n->Store);
- n->Store = NULL;
- }
- }
-#endif
-
- for (i = 0; i < 3; i++)
- _slang_free_ir(n->Children[i]);
- /* Do not free n->List since it's a child elsewhere */
- _slang_free(n);
-}
-
-
-/**
- * Recursively free an IR tree.
- */
-void
-_slang_free_ir_tree(slang_ir_node *n)
-{
-#if 0
- _slang_refcount_storage(n);
-#endif
- _slang_free_ir(n);
-}
-
-
-static const char *
-storage_string(const slang_ir_storage *st)
-{
- static const char *files[] = {
- "TEMP",
- "LOCAL_PARAM",
- "ENV_PARAM",
- "STATE",
- "INPUT",
- "OUTPUT",
- "NAMED_PARAM",
- "CONSTANT",
- "UNIFORM",
- "VARYING",
- "WRITE_ONLY",
- "ADDRESS",
- "SAMPLER",
- "UNDEFINED"
- };
- static char s[100];
- assert(Elements(files) == PROGRAM_FILE_MAX);
-#if 0
- if (st->Size == 1)
- _mesa_snprintf(s, "%s[%d]", files[st->File], st->Index);
- else
- _mesa_snprintf(s, "%s[%d..%d]", files[st->File], st->Index,
- st->Index + st->Size - 1);
-#endif
- assert(st->File < (GLint) (sizeof(files) / sizeof(files[0])));
- _mesa_snprintf(s, sizeof(s), "%s[%d]", files[st->File], st->Index);
- return s;
-}
-
-
-static void
-spaces(int n)
-{
- while (n-- > 0) {
- printf(" ");
- }
-}
-
-
-void
-_slang_print_ir_tree(const slang_ir_node *n, int indent)
-{
-#define IND 0
-
- if (!n)
- return;
-#if !IND
- if (n->Opcode != IR_SEQ)
-#else
- printf("%3d:", indent);
-#endif
- spaces(indent);
-
- switch (n->Opcode) {
- case IR_SEQ:
-#if IND
- printf("SEQ at %p\n", (void*) n);
-#endif
- assert(n->Children[0]);
- assert(n->Children[1]);
- _slang_print_ir_tree(n->Children[0], indent + IND);
- _slang_print_ir_tree(n->Children[1], indent + IND);
- break;
- case IR_SCOPE:
- printf("NEW SCOPE\n");
- assert(!n->Children[1]);
- _slang_print_ir_tree(n->Children[0], indent + 3);
- break;
- case IR_COPY:
- printf("COPY\n");
- _slang_print_ir_tree(n->Children[0], indent+3);
- _slang_print_ir_tree(n->Children[1], indent+3);
- break;
- case IR_LABEL:
- printf("LABEL: %s\n", n->Label->Name);
- break;
- case IR_COND:
- printf("COND\n");
- _slang_print_ir_tree(n->Children[0], indent + 3);
- break;
-
- case IR_IF:
- printf("IF \n");
- _slang_print_ir_tree(n->Children[0], indent+3);
- spaces(indent);
- printf("THEN\n");
- _slang_print_ir_tree(n->Children[1], indent+3);
- if (n->Children[2]) {
- spaces(indent);
- printf("ELSE\n");
- _slang_print_ir_tree(n->Children[2], indent+3);
- }
- spaces(indent);
- printf("ENDIF\n");
- break;
-
- case IR_BEGIN_SUB:
- printf("BEGIN_SUB\n");
- break;
- case IR_END_SUB:
- printf("END_SUB\n");
- break;
- case IR_RETURN:
- printf("RETURN\n");
- break;
- case IR_CALL:
- printf("CALL %s\n", n->Label->Name);
- break;
-
- case IR_LOOP:
- printf("LOOP\n");
- _slang_print_ir_tree(n->Children[0], indent+3);
- if (n->Children[1]) {
- spaces(indent);
- printf("TAIL:\n");
- _slang_print_ir_tree(n->Children[1], indent+3);
- }
- spaces(indent);
- printf("ENDLOOP\n");
- break;
- case IR_CONT:
- printf("CONT\n");
- break;
- case IR_BREAK:
- printf("BREAK\n");
- break;
- case IR_BREAK_IF_TRUE:
- printf("BREAK_IF_TRUE\n");
- _slang_print_ir_tree(n->Children[0], indent+3);
- break;
- case IR_CONT_IF_TRUE:
- printf("CONT_IF_TRUE\n");
- _slang_print_ir_tree(n->Children[0], indent+3);
- break;
-
- case IR_VAR:
- printf("VAR %s%s at %s store %p\n",
- (n->Var ? (char *) n->Var->a_name : "TEMP"),
- _mesa_swizzle_string(n->Store->Swizzle, 0, 0),
- storage_string(n->Store), (void*) n->Store);
- break;
- case IR_VAR_DECL:
- printf("VAR_DECL %s (%p) at %s store %p\n",
- (n->Var ? (char *) n->Var->a_name : "TEMP"),
- (void*) n->Var, storage_string(n->Store),
- (void*) n->Store);
- break;
- case IR_FIELD:
- printf("FIELD %s of\n", n->Field);
- _slang_print_ir_tree(n->Children[0], indent+3);
- break;
- case IR_FLOAT:
- printf("FLOAT %g %g %g %g\n",
- n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
- break;
- case IR_I_TO_F:
- printf("INT_TO_FLOAT\n");
- _slang_print_ir_tree(n->Children[0], indent+3);
- break;
- case IR_F_TO_I:
- printf("FLOAT_TO_INT\n");
- _slang_print_ir_tree(n->Children[0], indent+3);
- break;
- case IR_SWIZZLE:
- printf("SWIZZLE %s of (store %p) \n",
- _mesa_swizzle_string(n->Store->Swizzle, 0, 0), (void*) n->Store);
- _slang_print_ir_tree(n->Children[0], indent + 3);
- break;
- default:
- printf("%s (%p, %p) (store %p)\n", _slang_ir_name(n->Opcode),
- (void*) n->Children[0], (void*) n->Children[1], (void*) n->Store);
- _slang_print_ir_tree(n->Children[0], indent+3);
- _slang_print_ir_tree(n->Children[1], indent+3);
- }
-}
diff --git a/src/mesa/slang/slang_ir.h b/src/mesa/slang/slang_ir.h
deleted file mode 100644
index ce9a6c5a483..00000000000
--- a/src/mesa/slang/slang_ir.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 VMware, 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.
- */
-
-/**
- * \file slang_ir.h
- * Mesa GLSL Intermediate Representation tree types and constants.
- * \author Brian Paul
- */
-
-
-#ifndef SLANG_IR_H
-#define SLANG_IR_H
-
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_label.h"
-#include "main/mtypes.h"
-#include "program/prog_instruction.h"
-
-
-/**
- * Intermediate Representation opcodes
- */
-typedef enum
-{
- IR_NOP = 0,
- IR_SEQ, /* sequence (eval left, then right) */
- IR_SCOPE, /* new variable scope (one child) */
-
- IR_LABEL, /* target of a jump or cjump */
-
- IR_COND, /* conditional expression/predicate */
-
- IR_IF, /* high-level IF/then/else */
- /* Children[0] = conditional expression */
- /* Children[1] = if-true part */
- /* Children[2] = if-else part, or NULL */
-
- IR_BEGIN_SUB, /* begin subroutine */
- IR_END_SUB, /* end subroutine */
- IR_RETURN, /* return from subroutine */
- IR_CALL, /* call subroutine */
-
- IR_LOOP, /* high-level loop-begin / loop-end */
- /* Children[0] = loop body */
- /* Children[1] = loop tail code, or NULL */
-
- IR_CONT, /* continue loop */
- /* n->Parent = ptr to parent IR_LOOP Node */
- IR_BREAK, /* break loop */
-
- IR_BREAK_IF_TRUE, /**< Children[0] = the condition expression */
- IR_CONT_IF_TRUE,
-
- IR_COPY, /**< assignment/copy */
- IR_MOVE, /**< assembly MOV instruction */
-
- /* vector ops: */
- IR_ADD, /**< assembly ADD instruction */
- IR_SUB,
- IR_MUL,
- IR_DIV,
- IR_DOT4,
- IR_DOT3,
- IR_DOT2,
- IR_NRM4,
- IR_NRM3,
- IR_CROSS, /* vec3 cross product */
- IR_LRP,
- IR_CLAMP,
- IR_MIN,
- IR_MAX,
- IR_CMP, /* = (op0 < 0) ? op1 : op2 */
- IR_SEQUAL, /* Set if args are equal (vector) */
- IR_SNEQUAL, /* Set if args are not equal (vector) */
- IR_SGE, /* Set if greater or equal (vector) */
- IR_SGT, /* Set if greater than (vector) */
- IR_SLE, /* Set if less or equal (vector) */
- IR_SLT, /* Set if less than (vector) */
- IR_POW, /* x^y */
- IR_EXP, /* e^x */
- IR_EXP2, /* 2^x */
- IR_LOG2, /* log base 2 */
- IR_RSQ, /* 1/sqrt() */
- IR_RCP, /* reciprocol */
- IR_FLOOR,
- IR_FRAC,
- IR_ABS, /* absolute value */
- IR_NEG, /* negate */
- IR_DDX, /* derivative w.r.t. X */
- IR_DDY, /* derivative w.r.t. Y */
- IR_SIN, /* sine */
- IR_COS, /* cosine */
- IR_NOISE1, /* noise(x) */
- IR_NOISE2, /* noise(x, y) */
- IR_NOISE3, /* noise(x, y, z) */
- IR_NOISE4, /* noise(x, y, z, w) */
-
- IR_EQUAL, /* boolean equality */
- IR_NOTEQUAL,/* boolean inequality */
- IR_NOT, /* boolean not */
-
- IR_VAR, /* variable reference */
- IR_VAR_DECL,/* var declaration */
-
- IR_ELEMENT, /* array element */
- IR_FIELD, /* struct field */
- IR_SWIZZLE, /* swizzled storage access */
-
- IR_TEX, /* texture lookup */
- IR_TEXB, /* texture lookup with LOD bias */
- IR_TEXP, /* texture lookup with projection */
-
- IR_TEX_SH, /* texture lookup, shadow compare */
- IR_TEXB_SH, /* texture lookup with LOD bias, shadow compare */
- IR_TEXP_SH, /* texture lookup with projection, shadow compare */
-
- IR_FLOAT,
- IR_I_TO_F, /* int[4] to float[4] conversion */
- IR_F_TO_I, /* float[4] to int[4] conversion */
-
- IR_KILL, /* fragment kill/discard */
-
- IR_EMIT_VERTEX, /* geometry shader: emit vertex */
- IR_END_PRIMITIVE /* geometry shader: end primitive */
-} slang_ir_opcode;
-
-
-/**
- * Describes where data/variables are stored in the various register files.
- *
- * In the simple case, the File, Index and Size fields indicate where
- * a variable is stored. For example, a vec3 variable may be stored
- * as (File=PROGRAM_TEMPORARY, Index=6, Size=3). Or, File[Index].
- * Or, a program input like color may be stored as
- * (File=PROGRAM_INPUT,Index=3,Size=4);
- *
- * For single-float values, the Swizzle field indicates which component
- * of the vector contains the float.
- *
- * If IsIndirect is set, the storage is accessed through an indirect
- * register lookup. The value in question will be located at:
- * File[Index + IndirectFile[IndirectIndex]]
- *
- * This is primary used for indexing arrays. For example, consider this
- * GLSL code:
- * uniform int i;
- * float a[10];
- * float x = a[i];
- *
- * here, storage for a[i] would be described by (File=PROGRAM_TEMPORAY,
- * Index=aPos, IndirectFile=PROGRAM_UNIFORM, IndirectIndex=iPos), which
- * would mean TEMP[aPos + UNIFORM[iPos]]
- */
-struct slang_ir_storage_
-{
- gl_register_file File; /**< PROGRAM_TEMPORARY, PROGRAM_INPUT, etc */
- GLint Index; /**< -1 means unallocated */
- GLint Size; /**< number of floats or ints */
- GLuint Swizzle; /**< Swizzle AND writemask info */
- GLint RefCount; /**< Used during IR tree delete */
-
- GLboolean RelAddr; /* we'll remove this eventually */
-
- GLboolean IsIndirect;
- gl_register_file IndirectFile;
- GLint IndirectIndex;
- GLuint IndirectSwizzle;
- GLuint TexTarget; /**< If File==PROGRAM_SAMPLER, one of TEXTURE_x_INDEX */
-
- /* Is the register two-dimensional and
- * if so what's the second index */
- GLboolean Is2D;
- GLint Index2;
-
- /** If Parent is non-null, Index is relative to parent.
- * The other fields are ignored.
- */
- struct slang_ir_storage_ *Parent;
-};
-
-typedef struct slang_ir_storage_ slang_ir_storage;
-
-
-/**
- * Intermediate Representation (IR) tree node
- * Basically a binary tree, but IR_LRP and IR_CLAMP have three children.
- */
-typedef struct slang_ir_node_
-{
- slang_ir_opcode Opcode;
- struct slang_ir_node_ *Children[3];
- slang_ir_storage *Store; /**< location of result of this operation */
- GLint InstLocation; /**< Location of instruction emitted for this node */
-
- /** special fields depending on Opcode: */
- const char *Field; /**< If Opcode == IR_FIELD */
- GLfloat Value[4]; /**< If Opcode == IR_FLOAT */
- slang_variable *Var; /**< If Opcode == IR_VAR or IR_VAR_DECL */
- struct slang_ir_node_ *List; /**< For various linked lists */
- struct slang_ir_node_ *Parent; /**< Pointer to logical parent (ie. loop) */
- slang_label *Label; /**< Used for branches */
- const char *Comment; /**< If Opcode == IR_COMMENT */
-} slang_ir_node;
-
-
-
-/**
- * Assembly and IR info
- */
-typedef struct
-{
- slang_ir_opcode IrOpcode;
- const char *IrName;
- gl_inst_opcode InstOpcode;
- GLuint ResultSize, NumParams;
-} slang_ir_info;
-
-
-
-extern const slang_ir_info *
-_slang_ir_info(slang_ir_opcode opcode);
-
-
-extern void
-_slang_init_ir_storage(slang_ir_storage *st,
- gl_register_file file, GLint index, GLint size,
- GLuint swizzle);
-
-extern slang_ir_storage *
-_slang_new_ir_storage(gl_register_file file, GLint index, GLint size);
-
-
-extern slang_ir_storage *
-_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size,
- GLuint swizzle);
-
-extern slang_ir_storage *
-_slang_new_ir_storage_2d(gl_register_file file, GLint index, GLint index2d,
- GLint size, GLuint swizzle);
-
-extern slang_ir_storage *
-_slang_new_ir_storage_relative(GLint index, GLint size,
- slang_ir_storage *parent);
-
-
-extern slang_ir_storage *
-_slang_new_ir_storage_indirect(gl_register_file file,
- GLint index,
- GLint size,
- gl_register_file indirectFile,
- GLint indirectIndex,
- GLuint indirectSwizzle);
-
-extern slang_ir_storage *
-_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size);
-
-
-extern void
-_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src);
-
-
-extern void
-_slang_free_ir_tree(slang_ir_node *n);
-
-
-extern void
-_slang_print_ir_tree(const slang_ir_node *n, int indent);
-
-
-#endif /* SLANG_IR_H */
diff --git a/src/mesa/slang/slang_label.c b/src/mesa/slang/slang_label.c
deleted file mode 100644
index 24881d5b6e6..00000000000
--- a/src/mesa/slang/slang_label.c
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-/**
- * Functions for managing instruction labels.
- * Basically, this is used to manage the problem of forward branches where
- * we have a branch instruciton but don't know the target address yet.
- */
-
-
-#include "main/mtypes.h"
-#include "program/prog_instruction.h"
-#include "slang_label.h"
-#include "slang_mem.h"
-
-
-
-slang_label *
-_slang_label_new(const char *name)
-{
- slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
- if (l) {
- l->Name = _slang_strdup(name);
- l->Location = -1;
- }
- return l;
-}
-
-/**
- * As above, but suffix the name with a unique number.
- */
-slang_label *
-_slang_label_new_unique(const char *name)
-{
- static int id = 1;
- slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
- if (l) {
- l->Name = (char *) _slang_alloc(strlen(name) + 10);
- if (!l->Name) {
- free(l);
- return NULL;
- }
- _mesa_snprintf(l->Name, strlen(name) + 10, "%s_%d", name, id);
- id++;
- l->Location = -1;
- }
- return l;
-}
-
-void
-_slang_label_delete(slang_label *l)
-{
- if (l->Name) {
- _slang_free(l->Name);
- l->Name = NULL;
- }
- if (l->References) {
- _slang_free(l->References);
- l->References = NULL;
- }
- _slang_free(l);
-}
-
-
-void
-_slang_label_add_reference(slang_label *l, GLuint inst)
-{
- const GLuint oldSize = l->NumReferences * sizeof(GLuint);
- assert(l->Location < 0);
- l->References = _slang_realloc(l->References,
- oldSize, oldSize + sizeof(GLuint));
- if (l->References) {
- l->References[l->NumReferences] = inst;
- l->NumReferences++;
- }
-}
-
-
-GLint
-_slang_label_get_location(const slang_label *l)
-{
- return l->Location;
-}
-
-
-void
-_slang_label_set_location(slang_label *l, GLint location,
- struct gl_program *prog)
-{
- GLuint i;
-
- assert(l->Location < 0);
- assert(location >= 0);
-
- l->Location = location;
-
- /* for the instructions that were waiting to learn the label's location: */
- for (i = 0; i < l->NumReferences; i++) {
- const GLuint j = l->References[i];
- prog->Instructions[j].BranchTarget = location;
- }
-
- if (l->References) {
- _slang_free(l->References);
- l->References = NULL;
- }
-}
diff --git a/src/mesa/slang/slang_label.h b/src/mesa/slang/slang_label.h
deleted file mode 100644
index b0cff3a8e89..00000000000
--- a/src/mesa/slang/slang_label.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef SLANG_LABEL_H
-#define SLANG_LABEL_H 1
-
-#include "main/glheader.h"
-
-struct gl_program;
-
-struct slang_label_
-{
- char *Name;
- GLint Location;
- /**
- * List of instruction references (numbered starting at zero) which need
- * their BranchTarget field filled in with the location eventually
- * assigned to the label.
- */
- GLuint NumReferences;
- GLuint *References; /** Array [NumReferences] */
-};
-
-typedef struct slang_label_ slang_label;
-
-
-extern slang_label *
-_slang_label_new(const char *name);
-
-extern slang_label *
-_slang_label_new_unique(const char *name);
-
-extern void
-_slang_label_delete(slang_label *l);
-
-extern void
-_slang_label_add_reference(slang_label *l, GLuint inst);
-
-extern GLint
-_slang_label_get_location(const slang_label *l);
-
-extern void
-_slang_label_set_location(slang_label *l, GLint location,
- struct gl_program *prog);
-
-
-#endif /* SLANG_LABEL_H */
diff --git a/src/mesa/slang/slang_link.c b/src/mesa/slang/slang_link.c
deleted file mode 100644
index c21f67256a5..00000000000
--- a/src/mesa/slang/slang_link.c
+++ /dev/null
@@ -1,1287 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 VMware, 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.
- */
-
-/**
- * \file slang_link.c
- * GLSL linker
- * \author Brian Paul
- */
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "main/macros.h"
-#include "main/shaderapi.h"
-#include "main/shaderobj.h"
-#include "main/uniforms.h"
-#include "program/program.h"
-#include "program/prog_instruction.h"
-#include "program/prog_parameter.h"
-#include "program/prog_print.h"
-#include "program/prog_statevars.h"
-#include "program/prog_uniform.h"
-#include "slang_builtin.h"
-#include "slang_link.h"
-
-
-/** cast wrapper */
-static struct gl_vertex_program *
-vertex_program(struct gl_program *prog)
-{
- assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
- return (struct gl_vertex_program *) prog;
-}
-
-
-/** cast wrapper */
-static struct gl_fragment_program *
-fragment_program(struct gl_program *prog)
-{
- assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
- return (struct gl_fragment_program *) prog;
-}
-
-static struct gl_geometry_program *
-geometry_program(struct gl_program *prog)
-{
- assert(prog->Target == MESA_GEOMETRY_PROGRAM);
- return (struct gl_geometry_program *)prog;
-}
-
-/**
- * Record a linking error.
- */
-static void
-link_error(struct gl_shader_program *shProg, const char *msg)
-{
- if (shProg->InfoLog) {
- free(shProg->InfoLog);
- }
- shProg->InfoLog = _mesa_strdup(msg);
- shProg->LinkStatus = GL_FALSE;
-}
-
-
-
-/**
- * Check if the given bit is either set or clear in both bitfields.
- */
-static GLboolean
-bits_agree(GLbitfield flags1, GLbitfield flags2, GLbitfield bit)
-{
- return (flags1 & bit) == (flags2 & bit);
-}
-
-
-/**
- * Examine the outputs/varyings written by the vertex shader and
- * append the names of those outputs onto the Varyings list.
- * This will only capture the pre-defined/built-in varyings like
- * gl_Position, not user-defined varyings.
- */
-static void
-update_varying_var_list(GLcontext *ctx, struct gl_shader_program *shProg)
-{
- if (shProg->VertexProgram) {
- GLbitfield64 written = shProg->VertexProgram->Base.OutputsWritten;
- GLuint i;
- for (i = 0; written && i < VERT_RESULT_MAX; i++) {
- if (written & BITFIELD64_BIT(i)) {
- const char *name = _slang_vertex_output_name(i);
- if (name)
- _mesa_add_varying(shProg->Varying, name, 1, GL_FLOAT_VEC4, 0x0);
- written &= ~BITFIELD64_BIT(i);
- }
- }
- }
- if (shProg->GeometryProgram) {
- GLbitfield64 written = shProg->GeometryProgram->Base.OutputsWritten;
- GLuint i;
- for (i = 0; written && i < GEOM_RESULT_MAX; i++) {
- if (written & BITFIELD64_BIT(i)) {
- const char *name = _slang_geometry_output_name(i);
- if (name)
- _mesa_add_varying(shProg->Varying, name, 1, GL_FLOAT_VEC4, 0x0);
- written &= ~BITFIELD64_BIT(i);
- }
- }
- }
-}
-
-
-/**
- * Do link error checking related to transform feedback.
- */
-static GLboolean
-link_transform_feedback(GLcontext *ctx, struct gl_shader_program *shProg)
-{
- GLbitfield varyingMask;
- GLuint totalComps, maxComps, i;
-
- if (shProg->TransformFeedback.NumVarying == 0) {
- /* nothing to do */
- return GL_TRUE;
- }
-
- /* Check that there's a vertex shader */
- if (shProg->TransformFeedback.NumVarying > 0 &&
- !shProg->VertexProgram) {
- link_error(shProg, "Transform feedback without vertex shader");
- return GL_FALSE;
- }
-
- /* Check that all named variables exist, and that none are duplicated.
- * Also, build a count of the number of varying components to feedback.
- */
- totalComps = 0;
- varyingMask = 0x0;
- for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
- const GLchar *name = shProg->TransformFeedback.VaryingNames[i];
- GLint v = _mesa_lookup_parameter_index(shProg->Varying, -1, name);
- struct gl_program_parameter *p;
-
- if (v < 0) {
- char msg[100];
- _mesa_snprintf(msg, sizeof(msg),
- "vertex shader does not emit %s", name);
- link_error(shProg, msg);
- return GL_FALSE;
- }
-
- assert(v < MAX_VARYING);
-
- /* already seen this varying name? */
- if (varyingMask & (1 << v)) {
- char msg[100];
- _mesa_snprintf(msg, sizeof(msg),
- "duplicated transform feedback varying name: %s",
- name);
- link_error(shProg, msg);
- return GL_FALSE;
- }
-
- varyingMask |= (1 << v);
-
- p = &shProg->Varying->Parameters[v];
-
- totalComps += _mesa_sizeof_glsl_type(p->DataType);
- }
-
- if (shProg->TransformFeedback.BufferMode == GL_INTERLEAVED_ATTRIBS)
- maxComps = ctx->Const.MaxTransformFeedbackInterleavedComponents;
- else
- maxComps = ctx->Const.MaxTransformFeedbackSeparateComponents;
-
- /* check max varying components against the limit */
- if (totalComps > maxComps) {
- char msg[100];
- _mesa_snprintf(msg, sizeof(msg),
- "Too many feedback components: %u, max is %u",
- totalComps, maxComps);
- link_error(shProg, msg);
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Linking varying vars involves rearranging varying vars so that the
- * vertex program's output varyings matches the order of the fragment
- * program's input varyings.
- * We'll then rewrite instructions to replace PROGRAM_VARYING with either
- * PROGRAM_INPUT or PROGRAM_OUTPUT depending on whether it's a vertex or
- * fragment shader.
- * This is also where we set program Input/OutputFlags to indicate
- * which inputs are centroid-sampled, invariant, etc.
- */
-static GLboolean
-link_varying_vars(GLcontext *ctx,
- struct gl_shader_program *shProg, struct gl_program *prog)
-{
- GLuint *map, i, firstSrcVarying, firstDstVarying, newSrcFile, newDstFile;
- GLbitfield *inOutFlags = NULL;
-
- map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint));
- if (!map)
- return GL_FALSE;
-
- /* Varying variables are treated like other vertex program outputs
- * (and like other fragment program inputs). The position of the
- * first varying differs for vertex/fragment programs...
- * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT.
- */
- if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
- firstSrcVarying = firstDstVarying = VERT_RESULT_VAR0;
- newSrcFile = newDstFile = PROGRAM_OUTPUT;
- inOutFlags = prog->OutputFlags;
- }
- else if (prog->Target == MESA_GEOMETRY_PROGRAM) {
- firstSrcVarying = GEOM_ATTRIB_VAR0;
- newSrcFile = PROGRAM_INPUT;
- firstDstVarying = GEOM_RESULT_VAR0;
- newDstFile = PROGRAM_OUTPUT;
- }
- else {
- assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
- firstSrcVarying = firstDstVarying = FRAG_ATTRIB_VAR0;
- newSrcFile = newDstFile = PROGRAM_INPUT;
- inOutFlags = prog->InputFlags;
- }
-
- for (i = 0; i < prog->Varying->NumParameters; i++) {
- /* see if this varying is in the linked varying list */
- const struct gl_program_parameter *var = prog->Varying->Parameters + i;
- GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name);
- if (j >= 0) {
- /* varying is already in list, do some error checking */
- const struct gl_program_parameter *v =
- &shProg->Varying->Parameters[j];
- if (var->Size != v->Size) {
- link_error(shProg, "mismatched varying variable types");
- free(map);
- return GL_FALSE;
- }
- if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_CENTROID)) {
- char msg[100];
- _mesa_snprintf(msg, sizeof(msg),
- "centroid modifier mismatch for '%s'", var->Name);
- link_error(shProg, msg);
- free(map);
- return GL_FALSE;
- }
- if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_INVARIANT)) {
- char msg[100];
- _mesa_snprintf(msg, sizeof(msg),
- "invariant modifier mismatch for '%s'", var->Name);
- link_error(shProg, msg);
- free(map);
- return GL_FALSE;
- }
- }
- else {
- /* not already in linked list */
- j = _mesa_add_varying(shProg->Varying, var->Name, var->Size,
- var->DataType, var->Flags);
- }
-
- if (shProg->Varying->NumParameters > ctx->Const.MaxVarying) {
- link_error(shProg, "Too many varying variables");
- free(map);
- return GL_FALSE;
- }
-
- /* Map varying[i] to varying[j].
- * Note: the loop here takes care of arrays or large (sz>4) vars.
- */
- {
- GLint sz = var->Size;
- while (sz > 0) {
- inOutFlags[firstDstVarying + j] = var->Flags;
- /*printf("Link varying from %d to %d\n", i, j);*/
- map[i++] = j++;
- sz -= 4;
- }
- i--; /* go back one */
- }
- }
-
-
- /* OK, now scan the program/shader instructions looking for varying vars,
- * replacing the old index with the new index.
- */
- for (i = 0; i < prog->NumInstructions; i++) {
- struct prog_instruction *inst = prog->Instructions + i;
- GLuint j;
-
- if (inst->DstReg.File == PROGRAM_VARYING) {
- inst->DstReg.File = newDstFile;
- inst->DstReg.Index = map[ inst->DstReg.Index ] + firstDstVarying;
- }
-
- for (j = 0; j < 3; j++) {
- if (inst->SrcReg[j].File == PROGRAM_VARYING) {
- inst->SrcReg[j].File = newSrcFile;
- inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstSrcVarying;
- }
- }
- }
-
- free(map);
-
- /* these will get recomputed before linking is completed */
- prog->InputsRead = 0x0;
- prog->OutputsWritten = 0x0;
-
- return GL_TRUE;
-}
-
-
-/**
- * Build the shProg->Uniforms list.
- * This is basically a list/index of all uniforms found in either/both of
- * the vertex and fragment shaders.
- *
- * About uniforms:
- * Each uniform has two indexes, one that points into the vertex
- * program's parameter array and another that points into the fragment
- * program's parameter array. When the user changes a uniform's value
- * we have to change the value in the vertex and/or fragment program's
- * parameter array.
- *
- * This function will be called twice to set up the two uniform->parameter
- * mappings.
- *
- * If a uniform is only present in the vertex program OR fragment program
- * then the fragment/vertex parameter index, respectively, will be -1.
- */
-static GLboolean
-link_uniform_vars(GLcontext *ctx,
- struct gl_shader_program *shProg,
- struct gl_program *prog,
- GLuint *numSamplers)
-{
- GLuint samplerMap[200]; /* max number of samplers declared, not used */
- GLuint i;
-
- for (i = 0; i < prog->Parameters->NumParameters; i++) {
- const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
-
- /*
- * XXX FIX NEEDED HERE
- * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR.
- * For example, modelview matrix, light pos, etc.
- * Also, we need to update the state-var name-generator code to
- * generate GLSL-style names, like "gl_LightSource[0].position".
- * Furthermore, we'll need to fix the state-var's size/datatype info.
- */
-
- if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER)
- && p->Used) {
- /* add this uniform, indexing into the target's Parameters list */
- struct gl_uniform *uniform =
- _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i);
- if (uniform)
- uniform->Initialized = p->Initialized;
- }
-
- /* The samplerMap[] table we build here is used to remap/re-index
- * sampler references by TEX instructions.
- */
- if (p->Type == PROGRAM_SAMPLER && p->Used) {
- /* Allocate a new sampler index */
- GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0];
- GLuint newSampNum = *numSamplers;
- if (newSampNum >= ctx->Const.MaxTextureImageUnits) {
- char s[100];
- _mesa_snprintf(s, sizeof(s),
- "Too many texture samplers (%u, max is %u)",
- newSampNum, ctx->Const.MaxTextureImageUnits);
- link_error(shProg, s);
- return GL_FALSE;
- }
- /* save old->new mapping in the table */
- if (oldSampNum < Elements(samplerMap))
- samplerMap[oldSampNum] = newSampNum;
- /* update parameter's sampler index */
- prog->Parameters->ParameterValues[i][0] = (GLfloat) newSampNum;
- (*numSamplers)++;
- }
- }
-
- /* OK, now scan the program/shader instructions looking for texture
- * instructions using sampler vars. Replace old sampler indexes with
- * new ones.
- */
- prog->SamplersUsed = 0x0;
- for (i = 0; i < prog->NumInstructions; i++) {
- struct prog_instruction *inst = prog->Instructions + i;
- if (_mesa_is_tex_instruction(inst->Opcode)) {
- /* here, inst->TexSrcUnit is really the sampler unit */
- const GLint oldSampNum = inst->TexSrcUnit;
-
-#if 0
- printf("====== remap sampler from %d to %d\n",
- inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]);
-#endif
-
- if (oldSampNum < Elements(samplerMap)) {
- const GLuint newSampNum = samplerMap[oldSampNum];
- inst->TexSrcUnit = newSampNum;
- prog->SamplerTargets[newSampNum] = inst->TexSrcTarget;
- prog->SamplersUsed |= (1 << newSampNum);
- if (inst->TexShadow) {
- prog->ShadowSamplers |= (1 << newSampNum);
- }
- }
- }
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Resolve binding of generic vertex attributes.
- * For example, if the vertex shader declared "attribute vec4 foobar" we'll
- * allocate a generic vertex attribute for "foobar" and plug that value into
- * the vertex program instructions.
- * But if the user called glBindAttributeLocation(), those bindings will
- * have priority.
- */
-static GLboolean
-_slang_resolve_attributes(struct gl_shader_program *shProg,
- const struct gl_program *origProg,
- struct gl_program *linkedProg)
-{
- GLint attribMap[MAX_VERTEX_GENERIC_ATTRIBS];
- GLuint i, j;
- GLbitfield usedAttributes; /* generics only, not legacy attributes */
- GLbitfield inputsRead = 0x0;
-
- assert(origProg != linkedProg);
- assert(origProg->Target == GL_VERTEX_PROGRAM_ARB);
- assert(linkedProg->Target == GL_VERTEX_PROGRAM_ARB);
-
- if (!shProg->Attributes)
- shProg->Attributes = _mesa_new_parameter_list();
-
- if (linkedProg->Attributes) {
- _mesa_free_parameter_list(linkedProg->Attributes);
- }
- linkedProg->Attributes = _mesa_new_parameter_list();
-
-
- /* Build a bitmask indicating which attribute indexes have been
- * explicitly bound by the user with glBindAttributeLocation().
- */
- usedAttributes = 0x0;
- for (i = 0; i < shProg->Attributes->NumParameters; i++) {
- GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0];
- usedAttributes |= (1 << attr);
- }
-
- /* If gl_Vertex is used, that actually counts against the limit
- * on generic vertex attributes. This avoids the ambiguity of
- * whether glVertexAttrib4fv(0, v) sets legacy attribute 0 (vert pos)
- * or generic attribute[0]. If gl_Vertex is used, we want the former.
- */
- if (origProg->InputsRead & VERT_BIT_POS) {
- usedAttributes |= 0x1;
- }
-
- /* initialize the generic attribute map entries to -1 */
- for (i = 0; i < MAX_VERTEX_GENERIC_ATTRIBS; i++) {
- attribMap[i] = -1;
- }
-
- /*
- * Scan program for generic attribute references
- */
- for (i = 0; i < linkedProg->NumInstructions; i++) {
- struct prog_instruction *inst = linkedProg->Instructions + i;
- for (j = 0; j < 3; j++) {
- if (inst->SrcReg[j].File == PROGRAM_INPUT) {
- inputsRead |= (1 << inst->SrcReg[j].Index);
- }
-
- if (inst->SrcReg[j].File == PROGRAM_INPUT &&
- inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) {
- /*
- * OK, we've found a generic vertex attribute reference.
- */
- const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0;
-
- GLint attr = attribMap[k];
-
- if (attr < 0) {
- /* Need to figure out attribute mapping now.
- */
- const char *name = origProg->Attributes->Parameters[k].Name;
- const GLint size = origProg->Attributes->Parameters[k].Size;
- const GLenum type =origProg->Attributes->Parameters[k].DataType;
- GLint index;
-
- /* See if there's a user-defined attribute binding for
- * this name.
- */
- index = _mesa_lookup_parameter_index(shProg->Attributes,
- -1, name);
- if (index >= 0) {
- /* Found a user-defined binding */
- attr = shProg->Attributes->Parameters[index].StateIndexes[0];
- }
- else {
- /* No user-defined binding, choose our own attribute number.
- * Start at 1 since generic attribute 0 always aliases
- * glVertex/position.
- */
- for (attr = 0; attr < MAX_VERTEX_GENERIC_ATTRIBS; attr++) {
- if (((1 << attr) & usedAttributes) == 0)
- break;
- }
- if (attr == MAX_VERTEX_GENERIC_ATTRIBS) {
- link_error(shProg, "Too many vertex attributes");
- return GL_FALSE;
- }
-
- /* mark this attribute as used */
- usedAttributes |= (1 << attr);
- }
-
- attribMap[k] = attr;
-
- /* Save the final name->attrib binding so it can be queried
- * with glGetAttributeLocation().
- */
- _mesa_add_attribute(linkedProg->Attributes, name,
- size, type, attr);
- }
-
- assert(attr >= 0);
-
- /* update the instruction's src reg */
- inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr;
- }
- }
- }
-
- /* Handle pre-defined attributes here (gl_Vertex, gl_Normal, etc).
- * When the user queries the active attributes we need to include both
- * the user-defined attributes and the built-in ones.
- */
- for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_GENERIC0; i++) {
- if (inputsRead & (1 << i)) {
- _mesa_add_attribute(linkedProg->Attributes,
- _slang_vert_attrib_name(i),
- 4, /* size in floats */
- _slang_vert_attrib_type(i),
- -1 /* attrib/input */);
- }
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Scan program instructions to update the program's NumTemporaries field.
- * Note: this implemenation relies on the code generator allocating
- * temps in increasing order (0, 1, 2, ... ).
- */
-static void
-_slang_count_temporaries(struct gl_program *prog)
-{
- GLuint i, j;
- GLint maxIndex = -1;
-
- for (i = 0; i < prog->NumInstructions; i++) {
- const struct prog_instruction *inst = prog->Instructions + i;
- const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
- for (j = 0; j < numSrc; j++) {
- if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
- if (maxIndex < inst->SrcReg[j].Index)
- maxIndex = inst->SrcReg[j].Index;
- }
- if (inst->DstReg.File == PROGRAM_TEMPORARY) {
- if (maxIndex < (GLint) inst->DstReg.Index)
- maxIndex = inst->DstReg.Index;
- }
- }
- }
-
- prog->NumTemporaries = (GLuint) (maxIndex + 1);
-}
-
-
-/**
- * If an input attribute is indexed with relative addressing we have
- * to compute a gl_program::InputsRead bitmask which reflects the fact
- * that any input may be referenced by array element. Ex: gl_TexCoord[i].
- * This function computes the bitmask of potentially read inputs.
- */
-static GLbitfield
-get_inputs_read_mask(GLenum target, GLuint index, GLboolean relAddr)
-{
- GLbitfield mask;
-
- mask = 1 << index;
-
- if (relAddr) {
- if (target == GL_VERTEX_PROGRAM_ARB) {
- switch (index) {
- case VERT_ATTRIB_TEX0:
- mask = ((1U << (VERT_ATTRIB_TEX7 + 1)) - 1)
- - ((1U << VERT_ATTRIB_TEX0) - 1);
- break;
- case VERT_ATTRIB_GENERIC0:
- /* different code to avoid uint overflow */
- mask = ~0x0U - ((1U << VERT_ATTRIB_GENERIC0) - 1);
- break;
- default:
- ; /* a non-array input attribute */
- }
- }
- else if (target == GL_FRAGMENT_PROGRAM_ARB) {
- switch (index) {
- case FRAG_ATTRIB_TEX0:
- mask = ((1U << (FRAG_ATTRIB_TEX7 + 1)) - 1)
- - ((1U << FRAG_ATTRIB_TEX0) - 1);
- break;
- case FRAG_ATTRIB_VAR0:
- mask = ((1U << (FRAG_ATTRIB_VAR0 + MAX_VARYING)) - 1)
- - ((1U << FRAG_ATTRIB_VAR0) - 1);
- break;
- default:
- ; /* a non-array input attribute */
- }
- }
- else if (target == MESA_GEOMETRY_PROGRAM) {
- switch (index) {
- case GEOM_ATTRIB_VAR0:
- mask = ((1ULL << (GEOM_ATTRIB_VAR0 + MAX_VARYING)) - 1)
- - ((1ULL << GEOM_ATTRIB_VAR0) - 1);
- break;
- default:
- ; /* a non-array input attribute */
- }
- }
- else {
- assert(0 && "bad program target");
- }
- }
- else {
- }
-
- return mask;
-}
-
-
-/**
- * If an output attribute is indexed with relative addressing we have
- * to compute a gl_program::OutputsWritten bitmask which reflects the fact
- * that any output may be referenced by array element. Ex: gl_TexCoord[i].
- * This function computes the bitmask of potentially written outputs.
- */
-static GLbitfield64
-get_outputs_written_mask(GLenum target, GLuint index, GLboolean relAddr)
-{
- GLbitfield64 mask;
-
- mask = BITFIELD64_BIT(index);
-
- if (relAddr) {
- if (target == GL_VERTEX_PROGRAM_ARB) {
- switch (index) {
- case VERT_RESULT_TEX0:
- mask = BITFIELD64_RANGE(VERT_RESULT_TEX0,
- (VERT_RESULT_TEX0
- + MAX_TEXTURE_COORD_UNITS - 1));
- break;
- case VERT_RESULT_VAR0:
- mask = BITFIELD64_RANGE(VERT_RESULT_VAR0,
- (VERT_RESULT_VAR0 + MAX_VARYING - 1));
- break;
- default:
- ; /* a non-array output attribute */
- }
- }
- else if (target == GL_FRAGMENT_PROGRAM_ARB) {
- switch (index) {
- case FRAG_RESULT_DATA0:
- mask = BITFIELD64_RANGE(FRAG_RESULT_DATA0,
- (FRAG_RESULT_DATA0
- + MAX_DRAW_BUFFERS - 1));
- break;
- default:
- ; /* a non-array output attribute */
- }
- }
- else if (target == MESA_GEOMETRY_PROGRAM) {
- switch (index) {
- case GEOM_RESULT_TEX0:
- mask = BITFIELD64_RANGE(GEOM_RESULT_TEX0,
- (GEOM_RESULT_TEX0
- + MAX_TEXTURE_COORD_UNITS - 1));
- break;
- case GEOM_RESULT_VAR0:
- mask = BITFIELD64_RANGE(GEOM_RESULT_VAR0,
- (GEOM_RESULT_VAR0 + MAX_VARYING - 1));
- break;
- default:
- ; /* a non-array output attribute */
- }
- }
- else {
- assert(0 && "bad program target");
- }
- }
-
- return mask;
-}
-
-
-/**
- * Scan program instructions to update the program's InputsRead and
- * OutputsWritten fields.
- */
-static void
-_slang_update_inputs_outputs(struct gl_program *prog)
-{
- GLuint i, j;
- GLuint maxAddrReg = 0;
-
- prog->InputsRead = 0x0;
- prog->OutputsWritten = 0x0;
-
- prog->IndirectRegisterFiles = 0x0;
-
- for (i = 0; i < prog->NumInstructions; i++) {
- const struct prog_instruction *inst = prog->Instructions + i;
- const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
- for (j = 0; j < numSrc; j++) {
- if (inst->SrcReg[j].File == PROGRAM_INPUT) {
- if (prog->Target == MESA_GEOMETRY_PROGRAM &&
- inst->SrcReg[j].HasIndex2)
- prog->InputsRead |= get_inputs_read_mask(prog->Target,
- inst->SrcReg[j].Index2,
- inst->SrcReg[j].RelAddr2);
- else
- prog->InputsRead |= get_inputs_read_mask(prog->Target,
- inst->SrcReg[j].Index,
- inst->SrcReg[j].RelAddr);
- }
- else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
- maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
- }
-
- if (inst->SrcReg[j].RelAddr)
- prog->IndirectRegisterFiles |= (1 << inst->SrcReg[j].File);
- }
-
- if (inst->DstReg.File == PROGRAM_OUTPUT) {
- prog->OutputsWritten |= get_outputs_written_mask(prog->Target,
- inst->DstReg.Index,
- inst->DstReg.RelAddr);
- }
- else if (inst->DstReg.File == PROGRAM_ADDRESS) {
- maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);
- }
- if (inst->DstReg.RelAddr)
- prog->IndirectRegisterFiles |= (1 << inst->DstReg.File);
- }
- prog->NumAddressRegs = maxAddrReg;
-}
-
-
-
-/**
- * Remove extra #version directives from the concatenated source string.
- * Disable the extra ones by converting first two chars to //, a comment.
- * This is a bit of hack to work around a preprocessor bug that only
- * allows one #version directive per source.
- */
-static void
-remove_extra_version_directives(GLchar *source)
-{
- GLuint verCount = 0;
- while (1) {
- char *ver = strstr(source, "#version");
- if (ver) {
- verCount++;
- if (verCount > 1) {
- ver[0] = '/';
- ver[1] = '/';
- }
- source += 8;
- }
- else {
- break;
- }
- }
-}
-
-/* Returns the number of vertices per geometry shader
- * input primitive.
- * XXX: duplicated in Gallium in u_vertices_per_prim
- * method. Once Mesa core will start using Gallium
- * this should be removed
- */
-static int
-vertices_per_prim(int prim)
-{
- switch (prim) {
- case GL_POINTS:
- return 1;
- case GL_LINES:
- return 2;
- case GL_TRIANGLES:
- return 3;
- case GL_LINES_ADJACENCY_ARB:
- return 4;
- case GL_TRIANGLES_ADJACENCY_ARB:
- return 6;
- default:
- ASSERT(!"Bad primitive");
- return 3;
- }
-}
-
-/**
- * Return a new shader whose source code is the concatenation of
- * all the shader sources of the given type.
- */
-static struct gl_shader *
-concat_shaders(struct gl_shader_program *shProg, GLenum shaderType)
-{
- struct gl_shader *newShader;
- const struct gl_shader *firstShader = NULL;
- GLuint *shaderLengths;
- GLchar *source;
- GLuint totalLen = 0, len = 0;
- GLuint i;
-
- shaderLengths = (GLuint *)malloc(shProg->NumShaders * sizeof(GLuint));
- if (!shaderLengths) {
- return NULL;
- }
-
- /* compute total size of new shader source code */
- for (i = 0; i < shProg->NumShaders; i++) {
- const struct gl_shader *shader = shProg->Shaders[i];
- if (shader->Type == shaderType) {
- shaderLengths[i] = strlen(shader->Source);
- totalLen += shaderLengths[i];
- if (!firstShader)
- firstShader = shader;
- }
- }
-
- if (totalLen == 0) {
- free(shaderLengths);
- return NULL;
- }
-
- /* Geometry shader will inject definition of
- * const int gl_VerticesIn */
- if (shaderType == GL_GEOMETRY_SHADER_ARB) {
- totalLen += 32;
- }
-
- source = (GLchar *) malloc(totalLen + 1);
- if (!source) {
- free(shaderLengths);
- return NULL;
- }
-
- /* concatenate shaders */
- for (i = 0; i < shProg->NumShaders; i++) {
- const struct gl_shader *shader = shProg->Shaders[i];
- if (shader->Type == shaderType) {
- memcpy(source + len, shader->Source, shaderLengths[i]);
- len += shaderLengths[i];
- }
- }
- /* if it's geometry shader we need to inject definition
- * of "const int gl_VerticesIn = X;" where X is the number
- * of vertices per input primitive
- */
- if (shaderType == GL_GEOMETRY_SHADER_ARB) {
- GLchar gs_pre[32];
- GLuint num_verts = vertices_per_prim(shProg->Geom.InputType);
- _mesa_snprintf(gs_pre, 31,
- "const int gl_VerticesIn = %d;\n", num_verts);
- memcpy(source + len, gs_pre, strlen(gs_pre));
- len += strlen(gs_pre);
- }
- source[len] = '\0';
- /*
- printf("---NEW CONCATENATED SHADER---:\n%s\n------------\n", source);
- */
-
- free(shaderLengths);
-
- remove_extra_version_directives(source);
-
- newShader = CALLOC_STRUCT(gl_shader);
- if (!newShader) {
- free(source);
- return NULL;
- }
-
- newShader->Type = shaderType;
- newShader->Source = source;
- newShader->Pragmas = firstShader->Pragmas;
-
- return newShader;
-}
-
-/**
- * Search the shader program's list of shaders to find the one that
- * defines main().
- * This will involve shader concatenation and recompilation if needed.
- */
-static struct gl_shader *
-get_main_shader(GLcontext *ctx,
- struct gl_shader_program *shProg, GLenum type)
-{
- struct gl_shader *shader = NULL;
- GLuint i;
-
- /*
- * Look for a shader that defines main() and has no unresolved references.
- */
- for (i = 0; i < shProg->NumShaders; i++) {
- shader = shProg->Shaders[i];
- if (shader->Type == type &&
- shader->Main &&
- !shader->UnresolvedRefs) {
- /* All set! */
- return shader;
- }
- }
-
- /*
- * There must have been unresolved references during the original
- * compilation. Try concatenating all the shaders of the given type
- * and recompile that.
- */
- shader = concat_shaders(shProg, type);
-
- if (shader) {
- _slang_compile(ctx, shader);
-
- /* Finally, check if recompiling failed */
- if (!shader->CompileStatus ||
- !shader->Main ||
- shader->UnresolvedRefs) {
- link_error(shProg, "Unresolved symbols");
- ctx->Driver.DeleteShader(ctx, shader);
- return NULL;
- }
- }
-
- return shader;
-}
-
-
-/**
- * Shader linker. Currently:
- *
- * 1. The last attached vertex shader and fragment shader are linked.
- * 2. Varying vars in the two shaders are combined so their locations
- * agree between the vertex and fragment stages. They're treated as
- * vertex program output attribs and as fragment program input attribs.
- * 3. The vertex and fragment programs are cloned and modified to update
- * src/dst register references so they use the new, linked varying
- * storage locations.
- */
-void
-_slang_link(GLcontext *ctx,
- GLhandleARB programObj,
- struct gl_shader_program *shProg)
-{
- const struct gl_vertex_program *vertProg = NULL;
- const struct gl_fragment_program *fragProg = NULL;
- const struct gl_geometry_program *geomProg = NULL;
- GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE, geomNotify = GL_TRUE;
- GLuint numSamplers = 0;
- GLuint i;
-
- _mesa_clear_shader_program_data(ctx, shProg);
-
- /* Initialize LinkStatus to "success". Will be cleared if error. */
- shProg->LinkStatus = GL_TRUE;
-
- /* check that all programs compiled successfully */
- for (i = 0; i < shProg->NumShaders; i++) {
- if (!shProg->Shaders[i]->CompileStatus) {
- link_error(shProg, "linking with uncompiled shader\n");
- return;
- }
- }
-
- shProg->Uniforms = _mesa_new_uniform_list();
- shProg->Varying = _mesa_new_parameter_list();
-
- /*
- * Find the vertex and fragment shaders which define main()
- */
- {
- struct gl_shader *vertShader, *fragShader, *geomShader;
- vertShader = get_main_shader(ctx, shProg, GL_VERTEX_SHADER);
- geomShader = get_main_shader(ctx, shProg, GL_GEOMETRY_SHADER_ARB);
- fragShader = get_main_shader(ctx, shProg, GL_FRAGMENT_SHADER);
-
- if (vertShader)
- vertProg = vertex_program(vertShader->Program);
- if (geomShader)
- geomProg = geometry_program(geomShader->Program);
- if (fragShader)
- fragProg = fragment_program(fragShader->Program);
- if (!shProg->LinkStatus)
- return;
- }
-
-#if FEATURE_es2_glsl
- /* must have both a vertex and fragment program for ES2 */
- if (ctx->API == API_OPENGLES2) {
- if (!vertProg) {
- link_error(shProg, "missing vertex shader\n");
- return;
- }
- if (!fragProg) {
- link_error(shProg, "missing fragment shader\n");
- return;
- }
- }
-#endif
-
- /*
- * Make copies of the vertex/fragment programs now since we'll be
- * changing src/dst registers after merging the uniforms and varying vars.
- */
- _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
- if (vertProg) {
- struct gl_vertex_program *linked_vprog =
- _mesa_clone_vertex_program(ctx, vertProg);
- shProg->VertexProgram = linked_vprog; /* refcount OK */
- /* vertex program ID not significant; just set Id for debugging purposes */
- shProg->VertexProgram->Base.Id = shProg->Name;
- ASSERT(shProg->VertexProgram->Base.RefCount == 1);
- }
- _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL);
- if (geomProg) {
- struct gl_geometry_program *linked_gprog =
- _mesa_clone_geometry_program(ctx, geomProg);
- shProg->GeometryProgram = linked_gprog; /* refcount OK */
- shProg->GeometryProgram->Base.Id = shProg->Name;
- ASSERT(shProg->GeometryProgram->Base.RefCount == 1);
- }
- _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
- if (fragProg) {
- struct gl_fragment_program *linked_fprog =
- _mesa_clone_fragment_program(ctx, fragProg);
- shProg->FragmentProgram = linked_fprog; /* refcount OK */
- /* vertex program ID not significant; just set Id for debugging purposes */
- shProg->FragmentProgram->Base.Id = shProg->Name;
- ASSERT(shProg->FragmentProgram->Base.RefCount == 1);
- }
-
- /* link varying vars */
- if (shProg->VertexProgram) {
- if (!link_varying_vars(ctx, shProg, &shProg->VertexProgram->Base))
- return;
- }
- if (shProg->GeometryProgram) {
- if (!link_varying_vars(ctx, shProg, &shProg->GeometryProgram->Base))
- return;
- }
- if (shProg->FragmentProgram) {
- if (!link_varying_vars(ctx, shProg, &shProg->FragmentProgram->Base))
- return;
- }
-
- /* link uniform vars */
- if (shProg->VertexProgram) {
- if (!link_uniform_vars(ctx, shProg, &shProg->VertexProgram->Base,
- &numSamplers)) {
- return;
- }
- }
- if (shProg->GeometryProgram) {
- if (!link_uniform_vars(ctx, shProg, &shProg->GeometryProgram->Base,
- &numSamplers)) {
- return;
- }
- }
- if (shProg->FragmentProgram) {
- if (!link_uniform_vars(ctx, shProg, &shProg->FragmentProgram->Base,
- &numSamplers)) {
- return;
- }
- }
-
- /*_mesa_print_uniforms(shProg->Uniforms);*/
-
- if (shProg->VertexProgram) {
- if (!_slang_resolve_attributes(shProg, &vertProg->Base,
- &shProg->VertexProgram->Base)) {
- return;
- }
- }
-
- if (shProg->VertexProgram) {
- _slang_update_inputs_outputs(&shProg->VertexProgram->Base);
- _slang_count_temporaries(&shProg->VertexProgram->Base);
- if (!(shProg->VertexProgram->Base.OutputsWritten
- & BITFIELD64_BIT(VERT_RESULT_HPOS))) {
- /* the vertex program did not compute a vertex position */
- link_error(shProg,
- "gl_Position was not written by vertex shader\n");
- return;
- }
- }
- if (shProg->GeometryProgram) {
- if (!shProg->VertexProgram) {
- link_error(shProg,
- "Geometry shader without a vertex shader is illegal!\n");
- return;
- }
- if (shProg->Geom.VerticesOut == 0) {
- link_error(shProg,
- "GEOMETRY_VERTICES_OUT is zero\n");
- return;
- }
-
- _slang_count_temporaries(&shProg->GeometryProgram->Base);
- _slang_update_inputs_outputs(&shProg->GeometryProgram->Base);
- }
- if (shProg->FragmentProgram) {
- _slang_count_temporaries(&shProg->FragmentProgram->Base);
- _slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
- }
-
- /* Check that all the varying vars needed by the fragment shader are
- * actually produced by the vertex shader.
- */
- if (shProg->FragmentProgram) {
- const GLbitfield varyingRead
- = shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0;
- const GLbitfield64 varyingWritten = shProg->VertexProgram ?
- shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0;
- if ((varyingRead & varyingWritten) != varyingRead) {
- link_error(shProg,
- "Fragment program using varying vars not written by vertex shader\n");
- return;
- }
- }
-
- /* check that gl_FragColor and gl_FragData are not both written to */
- if (shProg->FragmentProgram) {
- const GLbitfield64 outputsWritten =
- shProg->FragmentProgram->Base.OutputsWritten;
- if ((outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
- (outputsWritten >= BITFIELD64_BIT(FRAG_RESULT_DATA0))) {
- link_error(shProg, "Fragment program cannot write both gl_FragColor"
- " and gl_FragData[].\n");
- return;
- }
- }
-
- update_varying_var_list(ctx, shProg);
-
- /* checks related to transform feedback */
- if (!link_transform_feedback(ctx, shProg)) {
- return;
- }
-
- if (fragProg && shProg->FragmentProgram) {
- /* Compute initial program's TexturesUsed info */
- _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
-
- /* notify driver that a new fragment program has been compiled/linked */
- vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
- &shProg->FragmentProgram->Base);
- if (ctx->Shader.Flags & GLSL_DUMP) {
- fprintf(stderr, "Mesa pre-link fragment program:\n");
- _mesa_print_program(&fragProg->Base);
- _mesa_print_program_parameters(ctx, &fragProg->Base);
-
- fprintf(stderr, "Mesa post-link fragment program:\n");
- _mesa_print_program(&shProg->FragmentProgram->Base);
- _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base);
- }
- }
-
- if (geomProg && shProg->GeometryProgram) {
- /* Compute initial program's TexturesUsed info */
- _mesa_update_shader_textures_used(&shProg->GeometryProgram->Base);
-
- /* Copy some per-shader-program fields to per-shader object */
- shProg->GeometryProgram->VerticesOut = shProg->Geom.VerticesOut;
- shProg->GeometryProgram->InputType = shProg->Geom.InputType;
- shProg->GeometryProgram->OutputType = shProg->Geom.OutputType;
-
- /* notify driver that a new fragment program has been compiled/linked */
- geomNotify = ctx->Driver.ProgramStringNotify(ctx, MESA_GEOMETRY_PROGRAM,
- &shProg->GeometryProgram->Base);
- if (ctx->Shader.Flags & GLSL_DUMP) {
- fprintf(stderr, "Mesa pre-link geometry program:\n");
- _mesa_print_program(&geomProg->Base);
- _mesa_print_program_parameters(ctx, &geomProg->Base);
-
- fprintf(stderr, "Mesa post-link geometry program:\n");
- _mesa_print_program(&shProg->GeometryProgram->Base);
- _mesa_print_program_parameters(ctx, &shProg->GeometryProgram->Base);
- }
- }
-
- if (vertProg && shProg->VertexProgram) {
- /* Compute initial program's TexturesUsed info */
- _mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
-
- /* notify driver that a new vertex program has been compiled/linked */
- fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
- &shProg->VertexProgram->Base);
- if (ctx->Shader.Flags & GLSL_DUMP) {
- fprintf(stderr, "Mesa pre-link vertex program:\n");
- _mesa_print_program(&vertProg->Base);
- _mesa_print_program_parameters(ctx, &vertProg->Base);
-
- fprintf(stderr, "Mesa post-link vertex program:\n");
- _mesa_print_program(&shProg->VertexProgram->Base);
- _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base);
- }
- }
-
- /* Debug: */
- if (0) {
- if (shProg->VertexProgram)
- _mesa_postprocess_program(ctx, &shProg->VertexProgram->Base);
- if (shProg->FragmentProgram)
- _mesa_postprocess_program(ctx, &shProg->FragmentProgram->Base);
- }
-
- if (ctx->Shader.Flags & GLSL_DUMP) {
- fprintf(stderr, "Varying vars:\n");
- _mesa_print_parameter_list(shProg->Varying);
- if (shProg->InfoLog) {
- fprintf(stderr, "Info Log: %s\n", shProg->InfoLog);
- }
- }
-
- if (!vertNotify || !fragNotify || !geomNotify) {
- /* driver rejected one/both of the vertex/fragment programs */
- if (!shProg->InfoLog) {
- link_error(shProg,
- "Vertex, geometry and/or fragment program rejected by driver\n");
- }
- }
- else {
- shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
- }
-}
-
diff --git a/src/mesa/slang/slang_log.c b/src/mesa/slang/slang_log.c
deleted file mode 100644
index 9ff21417bc5..00000000000
--- a/src/mesa/slang/slang_log.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.3
- *
- * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
- * Copyright (C) 2009 VMware, 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.
- */
-
-#include "main/imports.h"
-#include "slang_log.h"
-#include "slang_utility.h"
-
-
-
-static char *out_of_memory = "Error: Out of memory.\n";
-
-void
-slang_info_log_construct(slang_info_log * log)
-{
- log->text = NULL;
- log->dont_free_text = GL_FALSE;
- log->error_flag = GL_FALSE;
-}
-
-void
-slang_info_log_destruct(slang_info_log * log)
-{
- if (!log->dont_free_text)
- free(log->text);
-}
-
-static int
-slang_info_log_message(slang_info_log * log, const char *prefix,
- const char *msg)
-{
- GLuint size;
-
- if (log->dont_free_text)
- return 0;
- size = slang_string_length(msg) + 2;
- if (prefix != NULL)
- size += slang_string_length(prefix) + 2;
- if (log->text != NULL) {
- GLuint old_len = slang_string_length(log->text);
- log->text = (char *)
- _mesa_realloc(log->text, old_len + 1, old_len + size);
- }
- else {
- log->text = (char *) (malloc(size));
- if (log->text != NULL)
- log->text[0] = '\0';
- }
- if (log->text == NULL)
- return 0;
- if (prefix != NULL) {
- slang_string_concat(log->text, prefix);
- slang_string_concat(log->text, ": ");
- }
- slang_string_concat(log->text, msg);
- slang_string_concat(log->text, "\n");
-
- return 1;
-}
-
-int
-slang_info_log_print(slang_info_log * log, const char *msg, ...)
-{
- va_list va;
- char buf[1024];
-
- va_start(va, msg);
- vsprintf(buf, msg, va);
- va_end(va);
- return slang_info_log_message(log, NULL, buf);
-}
-
-int
-slang_info_log_error(slang_info_log * log, const char *msg, ...)
-{
- va_list va;
- char buf[1024];
-
- va_start(va, msg);
- vsprintf(buf, msg, va);
- va_end(va);
- log->error_flag = GL_TRUE;
- if (slang_info_log_message(log, "Error", buf))
- return 1;
- slang_info_log_memory(log);
- return 0;
-}
-
-int
-slang_info_log_warning(slang_info_log * log, const char *msg, ...)
-{
- va_list va;
- char buf[1024];
-
- va_start(va, msg);
- vsprintf(buf, msg, va);
- va_end(va);
- if (slang_info_log_message(log, "Warning", buf))
- return 1;
- slang_info_log_memory(log);
- return 0;
-}
-
-void
-slang_info_log_memory(slang_info_log * log)
-{
- if (!slang_info_log_message(log, "Error", "Out of memory.")) {
- log->dont_free_text = GL_TRUE;
- log->error_flag = GL_TRUE;
- log->text = out_of_memory;
- }
-}
diff --git a/src/mesa/slang/slang_mem.c b/src/mesa/slang/slang_mem.c
deleted file mode 100644
index 5eaa7c44272..00000000000
--- a/src/mesa/slang/slang_mem.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-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 slang_mem.c
- *
- * Memory manager for GLSL compiler. The general idea is to do all
- * allocations out of a large pool then just free the pool when done
- * compiling to avoid intricate malloc/free tracking and memory leaks.
- *
- * \author Brian Paul
- */
-
-#include "main/context.h"
-#include "main/macros.h"
-#include "slang_mem.h"
-
-
-#define GRANULARITY 8
-#define ROUND_UP(B) ( ((B) + (GRANULARITY - 1)) & ~(GRANULARITY - 1) )
-
-
-/** If 1, use conventional malloc/free. Helpful for debugging */
-#define USE_MALLOC_FREE 0
-
-
-struct slang_mempool_
-{
- GLuint Size, Used, Count, Largest;
- char *Data;
- struct slang_mempool_ *Next;
-};
-
-
-slang_mempool *
-_slang_new_mempool(GLuint initialSize)
-{
- slang_mempool *pool = (slang_mempool *) calloc(1, sizeof(slang_mempool));
- if (pool) {
- pool->Data = (char *) calloc(1, initialSize);
- /*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/
- if (!pool->Data) {
- free(pool);
- return NULL;
- }
- pool->Size = initialSize;
- pool->Used = 0;
- }
- return pool;
-}
-
-
-void
-_slang_delete_mempool(slang_mempool *pool)
-{
- GLuint total = 0;
- while (pool) {
- slang_mempool *next = pool->Next;
- /*
- printf("DELETE MEMPOOL %u / %u count=%u largest=%u\n",
- pool->Used, pool->Size, pool->Count, pool->Largest);
- */
- total += pool->Used;
- free(pool->Data);
- free(pool);
- pool = next;
- }
- /*printf("TOTAL ALLOCATED: %u\n", total);*/
-}
-
-
-#ifdef DEBUG
-static void
-check_zero(const char *addr, GLuint n)
-{
- GLuint i;
- for (i = 0; i < n; i++) {
- assert(addr[i]==0);
- }
-}
-#endif
-
-
-#ifdef DEBUG
-static GLboolean
-is_valid_address(const slang_mempool *pool, void *addr)
-{
- while (pool) {
- if ((char *) addr >= pool->Data &&
- (char *) addr < pool->Data + pool->Used)
- return GL_TRUE;
-
- pool = pool->Next;
- }
- return GL_FALSE;
-}
-#endif
-
-
-/**
- * Alloc 'bytes' from shader mempool.
- */
-void *
-_slang_alloc(GLuint bytes)
-{
-#if USE_MALLOC_FREE
- return calloc(1, bytes);
-#else
- slang_mempool *pool;
- GET_CURRENT_CONTEXT(ctx);
- pool = (slang_mempool *) ctx->Shader.MemPool;
-
- if (bytes == 0)
- bytes = 1;
-
- while (pool) {
- if (pool->Used + bytes <= pool->Size) {
- /* found room */
- void *addr = (void *) (pool->Data + pool->Used);
-#ifdef DEBUG
- check_zero((char*) addr, bytes);
-#endif
- pool->Used += ROUND_UP(bytes);
- pool->Largest = MAX2(pool->Largest, bytes);
- pool->Count++;
- /*printf("alloc %u Used %u\n", bytes, pool->Used);*/
- return addr;
- }
- else if (pool->Next) {
- /* try next block */
- pool = pool->Next;
- }
- else {
- /* alloc new pool */
- const GLuint sz = MAX2(bytes, pool->Size);
- pool->Next = _slang_new_mempool(sz);
- if (!pool->Next) {
- /* we're _really_ out of memory */
- return NULL;
- }
- else {
- pool = pool->Next;
- pool->Largest = bytes;
- pool->Count++;
- pool->Used = ROUND_UP(bytes);
-#ifdef DEBUG
- check_zero((char*) pool->Data, bytes);
-#endif
- return (void *) pool->Data;
- }
- }
- }
- return NULL;
-#endif
-}
-
-
-void *
-_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize)
-{
-#if USE_MALLOC_FREE
- return _mesa_realloc(oldBuffer, oldSize, newSize);
-#else
- GET_CURRENT_CONTEXT(ctx);
- slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
- (void) pool;
-
- if (newSize < oldSize) {
- return oldBuffer;
- }
- else {
- const GLuint copySize = (oldSize < newSize) ? oldSize : newSize;
- void *newBuffer = _slang_alloc(newSize);
-
- if (oldBuffer)
- ASSERT(is_valid_address(pool, oldBuffer));
-
- if (newBuffer && oldBuffer && copySize > 0)
- memcpy(newBuffer, oldBuffer, copySize);
-
- return newBuffer;
- }
-#endif
-}
-
-
-/**
- * Clone string, storing in current mempool.
- */
-char *
-_slang_strdup(const char *s)
-{
- if (s) {
- size_t l = strlen(s);
- char *s2 = (char *) _slang_alloc(l + 1);
- if (s2)
- strcpy(s2, s);
- return s2;
- }
- else {
- return NULL;
- }
-}
-
-
-/**
- * Don't actually free memory, but mark it (for debugging).
- */
-void
-_slang_free(void *addr)
-{
-#if USE_MALLOC_FREE
- free(addr);
-#else
- if (addr) {
- GET_CURRENT_CONTEXT(ctx);
- slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
- (void) pool;
- ASSERT(is_valid_address(pool, addr));
- }
-#endif
-}
diff --git a/src/mesa/slang/slang_print.c b/src/mesa/slang/slang_print.c
deleted file mode 100644
index 6b34f395fdf..00000000000
--- a/src/mesa/slang/slang_print.c
+++ /dev/null
@@ -1,883 +0,0 @@
-
-/**
- * Dump/print a slang_operation tree
- */
-
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_print.h"
-
-
-static void
-spaces(int n)
-{
- while (n--)
- printf(" ");
-}
-
-
-static void
-print_type(const slang_fully_specified_type *t)
-{
- switch (t->qualifier) {
- case SLANG_QUAL_NONE:
- /*printf("");*/
- break;
- case SLANG_QUAL_CONST:
- printf("const ");
- break;
- case SLANG_QUAL_ATTRIBUTE:
- printf("attrib ");
- break;
- case SLANG_QUAL_VARYING:
- printf("varying ");
- break;
- case SLANG_QUAL_UNIFORM:
- printf("uniform ");
- break;
- case SLANG_QUAL_OUT:
- printf("output ");
- break;
- case SLANG_QUAL_INOUT:
- printf("inout ");
- break;
- case SLANG_QUAL_FIXEDOUTPUT:
- printf("fixedoutput");
- break;
- case SLANG_QUAL_FIXEDINPUT:
- printf("fixedinput");
- break;
- default:
- printf("unknown qualifer!");
- }
-
- switch (t->specifier.type) {
- case SLANG_SPEC_VOID:
- printf("void");
- break;
- case SLANG_SPEC_BOOL:
- printf("bool");
- break;
- case SLANG_SPEC_BVEC2:
- printf("bvec2");
- break;
- case SLANG_SPEC_BVEC3:
- printf("bvec3");
- break;
- case SLANG_SPEC_BVEC4:
- printf("bvec4");
- break;
- case SLANG_SPEC_INT:
- printf("int");
- break;
- case SLANG_SPEC_IVEC2:
- printf("ivec2");
- break;
- case SLANG_SPEC_IVEC3:
- printf("ivec3");
- break;
- case SLANG_SPEC_IVEC4:
- printf("ivec4");
- break;
- case SLANG_SPEC_FLOAT:
- printf("float");
- break;
- case SLANG_SPEC_VEC2:
- printf("vec2");
- break;
- case SLANG_SPEC_VEC3:
- printf("vec3");
- break;
- case SLANG_SPEC_VEC4:
- printf("vec4");
- break;
- case SLANG_SPEC_MAT2:
- printf("mat2");
- break;
- case SLANG_SPEC_MAT3:
- printf("mat3");
- break;
- case SLANG_SPEC_MAT4:
- printf("mat4");
- break;
- case SLANG_SPEC_MAT23:
- printf("mat2x3");
- break;
- case SLANG_SPEC_MAT32:
- printf("mat3x2");
- break;
- case SLANG_SPEC_MAT24:
- printf("mat2x4");
- break;
- case SLANG_SPEC_MAT42:
- printf("mat4x2");
- break;
- case SLANG_SPEC_MAT34:
- printf("mat3x4");
- break;
- case SLANG_SPEC_MAT43:
- printf("mat4x3");
- break;
- case SLANG_SPEC_SAMPLER_1D:
- printf("sampler1D");
- break;
- case SLANG_SPEC_SAMPLER_2D:
- printf("sampler2D");
- break;
- case SLANG_SPEC_SAMPLER_3D:
- printf("sampler3D");
- break;
- case SLANG_SPEC_SAMPLER_CUBE:
- printf("samplerCube");
- break;
- case SLANG_SPEC_SAMPLER_1D_SHADOW:
- printf("sampler1DShadow");
- break;
- case SLANG_SPEC_SAMPLER_2D_SHADOW:
- printf("sampler2DShadow");
- break;
- case SLANG_SPEC_STRUCT:
- printf("struct");
- break;
- case SLANG_SPEC_ARRAY:
- printf("array");
- break;
- default:
- printf("unknown type");
- }
- /*printf("\n");*/
-}
-
-
-static void
-print_variable(const slang_variable *v, int indent)
-{
- spaces(indent);
- printf("VAR ");
- print_type(&v->type);
- printf(" %s (at %p)", (char *) v->a_name, (void *) v);
- if (v->initializer) {
- printf(" :=\n");
- slang_print_tree(v->initializer, indent + 3);
- }
- else {
- printf(";\n");
- }
-}
-
-
-static void
-print_binary(const slang_operation *op, const char *oper, int indent)
-{
- assert(op->num_children == 2);
-#if 0
- printf("binary at %p locals=%p outer=%p\n",
- (void *) op,
- (void *) op->locals,
- (void *) op->locals->outer_scope);
-#endif
- slang_print_tree(&op->children[0], indent + 3);
- spaces(indent);
- printf("%s at %p locals=%p outer=%p\n",
- oper, (void *) op, (void *) op->locals,
- (void *) op->locals->outer_scope);
- slang_print_tree(&op->children[1], indent + 3);
-}
-
-
-static void
-print_generic2(const slang_operation *op, const char *oper,
- const char *s, int indent)
-{
- GLuint i;
- if (oper) {
- spaces(indent);
- printf("%s %s at %p locals=%p outer=%p\n",
- oper, s, (void *) op, (void *) op->locals,
- (void *) op->locals->outer_scope);
- }
- for (i = 0; i < op->num_children; i++) {
- spaces(indent);
- printf("//child %u of %u:\n", i, op->num_children);
- slang_print_tree(&op->children[i], indent);
- }
-}
-
-static void
-print_generic(const slang_operation *op, const char *oper, int indent)
-{
- print_generic2(op, oper, "", indent);
-}
-
-
-static const slang_variable_scope *
-find_scope(const slang_variable_scope *s, slang_atom name)
-{
- GLuint i;
- for (i = 0; i < s->num_variables; i++) {
- if (s->variables[i]->a_name == name)
- return s;
- }
- if (s->outer_scope)
- return find_scope(s->outer_scope, name);
- else
- return NULL;
-}
-
-static const slang_variable *
-find_var(const slang_variable_scope *s, slang_atom name)
-{
- GLuint i;
- for (i = 0; i < s->num_variables; i++) {
- if (s->variables[i]->a_name == name)
- return s->variables[i];
- }
- if (s->outer_scope)
- return find_var(s->outer_scope, name);
- else
- return NULL;
-}
-
-
-void
-slang_print_tree(const slang_operation *op, int indent)
-{
- GLuint i;
-
- switch (op->type) {
-
- case SLANG_OPER_NONE:
- spaces(indent);
- printf("SLANG_OPER_NONE\n");
- break;
-
- case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
- spaces(indent);
- printf("{ locals=%p outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope);
- print_generic(op, NULL, indent+3);
- spaces(indent);
- printf("}\n");
- break;
-
- case SLANG_OPER_BLOCK_NEW_SCOPE:
- case SLANG_OPER_NON_INLINED_CALL:
- spaces(indent);
- printf("{{ // new scope locals=%p outer=%p: ",
- (void *) op->locals,
- (void *) op->locals->outer_scope);
- for (i = 0; i < op->locals->num_variables; i++) {
- printf("%s ", (char *) op->locals->variables[i]->a_name);
- }
- printf("\n");
- print_generic(op, NULL, indent+3);
- spaces(indent);
- printf("}}\n");
- break;
-
- case SLANG_OPER_VARIABLE_DECL:
- assert(op->num_children == 0 || op->num_children == 1);
- {
- slang_variable *v;
- v = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
- if (v) {
- const slang_variable_scope *scope;
- spaces(indent);
- printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope);
- print_type(&v->type);
- printf(" %s (%p)", (char *) op->a_id,
- (void *) find_var(op->locals, op->a_id));
-
- scope = find_scope(op->locals, op->a_id);
- printf(" (in scope %p) ", (void *) scope);
- assert(scope);
- if (op->num_children == 1) {
- printf(" :=\n");
- slang_print_tree(&op->children[0], indent + 3);
- }
- else if (v->initializer) {
- printf(" := INITIALIZER\n");
- slang_print_tree(v->initializer, indent + 3);
- }
- else {
- printf(";\n");
- }
- /*
- spaces(indent);
- printf("TYPE: ");
- print_type(&v->type);
- spaces(indent);
- printf("ADDR: %d size: %d\n", v->address, v->size);
- */
- }
- else {
- spaces(indent);
- printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
- }
- }
- break;
-
- case SLANG_OPER_ASM:
- spaces(indent);
- printf("ASM: %s at %p locals=%p outer=%p\n",
- (char *) op->a_id,
- (void *) op,
- (void *) op->locals,
- (void *) op->locals->outer_scope);
- print_generic(op, "ASM", indent+3);
- break;
-
- case SLANG_OPER_BREAK:
- spaces(indent);
- printf("BREAK\n");
- break;
-
- case SLANG_OPER_CONTINUE:
- spaces(indent);
- printf("CONTINUE\n");
- break;
-
- case SLANG_OPER_DISCARD:
- spaces(indent);
- printf("DISCARD\n");
- break;
-
- case SLANG_OPER_RETURN:
- spaces(indent);
- printf("RETURN\n");
- if (op->num_children > 0)
- slang_print_tree(&op->children[0], indent + 3);
- break;
-
- case SLANG_OPER_RETURN_INLINED:
- spaces(indent);
- printf("RETURN_INLINED\n");
- if (op->num_children > 0)
- slang_print_tree(&op->children[0], indent + 3);
- break;
-
- case SLANG_OPER_LABEL:
- spaces(indent);
- printf("LABEL %s\n", (char *) op->a_id);
- break;
-
- case SLANG_OPER_EXPRESSION:
- spaces(indent);
- printf("EXPR: locals=%p outer=%p\n",
- (void *) op->locals,
- (void *) op->locals->outer_scope);
- /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/
- slang_print_tree(&op->children[0], indent + 3);
- break;
-
- case SLANG_OPER_IF:
- spaces(indent);
- printf("IF\n");
- slang_print_tree(&op->children[0], indent + 3);
- spaces(indent);
- printf("THEN\n");
- slang_print_tree(&op->children[1], indent + 3);
- spaces(indent);
- printf("ELSE\n");
- slang_print_tree(&op->children[2], indent + 3);
- spaces(indent);
- printf("ENDIF\n");
- break;
-
- case SLANG_OPER_WHILE:
- assert(op->num_children == 2);
- spaces(indent);
- printf("WHILE LOOP: locals = %p\n", (void *) op->locals);
- indent += 3;
- spaces(indent);
- printf("WHILE cond:\n");
- slang_print_tree(&op->children[0], indent + 3);
- spaces(indent);
- printf("WHILE body:\n");
- slang_print_tree(&op->children[1], indent + 3);
- indent -= 3;
- spaces(indent);
- printf("END WHILE LOOP\n");
- break;
-
- case SLANG_OPER_DO:
- spaces(indent);
- printf("DO LOOP: locals = %p\n", (void *) op->locals);
- indent += 3;
- spaces(indent);
- printf("DO body:\n");
- slang_print_tree(&op->children[0], indent + 3);
- spaces(indent);
- printf("DO cond:\n");
- slang_print_tree(&op->children[1], indent + 3);
- indent -= 3;
- spaces(indent);
- printf("END DO LOOP\n");
- break;
-
- case SLANG_OPER_FOR:
- spaces(indent);
- printf("FOR LOOP: locals = %p\n", (void *) op->locals);
- indent += 3;
- spaces(indent);
- printf("FOR init:\n");
- slang_print_tree(&op->children[0], indent + 3);
- spaces(indent);
- printf("FOR condition:\n");
- slang_print_tree(&op->children[1], indent + 3);
- spaces(indent);
- printf("FOR step:\n");
- slang_print_tree(&op->children[2], indent + 3);
- spaces(indent);
- printf("FOR body:\n");
- slang_print_tree(&op->children[3], indent + 3);
- indent -= 3;
- spaces(indent);
- printf("ENDFOR\n");
- /*
- print_generic(op, "FOR", indent + 3);
- */
- break;
-
- case SLANG_OPER_VOID:
- spaces(indent);
- printf("(oper-void)\n");
- break;
-
- case SLANG_OPER_LITERAL_BOOL:
- spaces(indent);
- printf("LITERAL (");
- for (i = 0; i < op->literal_size; i++)
- printf("%s ", op->literal[0] ? "TRUE" : "FALSE");
- printf(")\n");
-
- break;
-
- case SLANG_OPER_LITERAL_INT:
- spaces(indent);
- printf("LITERAL (");
- for (i = 0; i < op->literal_size; i++)
- printf("%d ", (int) op->literal[i]);
- printf(")\n");
- break;
-
- case SLANG_OPER_LITERAL_FLOAT:
- spaces(indent);
- printf("LITERAL (");
- for (i = 0; i < op->literal_size; i++)
- printf("%f ", op->literal[i]);
- printf(")\n");
- break;
-
- case SLANG_OPER_IDENTIFIER:
- {
- const slang_variable_scope *scope;
- spaces(indent);
- if (op->var && op->var->a_name) {
- scope = find_scope(op->locals, op->var->a_name);
- printf("VAR %s (in scope %p)\n", (char *) op->var->a_name,
- (void *) scope);
- assert(scope);
- }
- else {
- scope = find_scope(op->locals, op->a_id);
- printf("VAR' %s (in scope %p) locals=%p outer=%p\n",
- (char *) op->a_id,
- (void *) scope,
- (void *) op->locals,
- (void *) op->locals->outer_scope);
- /*assert(scope);*/
- }
- }
- break;
-
- case SLANG_OPER_SEQUENCE:
- print_generic(op, "COMMA-SEQ", indent+3);
- break;
-
- case SLANG_OPER_ASSIGN:
- spaces(indent);
- printf("ASSIGNMENT locals=%p outer=%p\n",
- (void *) op->locals,
- (void *) op->locals->outer_scope);
- print_binary(op, ":=", indent);
- break;
-
- case SLANG_OPER_ADDASSIGN:
- spaces(indent);
- printf("ASSIGN\n");
- print_binary(op, "+=", indent);
- break;
-
- case SLANG_OPER_SUBASSIGN:
- spaces(indent);
- printf("ASSIGN\n");
- print_binary(op, "-=", indent);
- break;
-
- case SLANG_OPER_MULASSIGN:
- spaces(indent);
- printf("ASSIGN\n");
- print_binary(op, "*=", indent);
- break;
-
- case SLANG_OPER_DIVASSIGN:
- spaces(indent);
- printf("ASSIGN\n");
- print_binary(op, "/=", indent);
- break;
-
- /*SLANG_OPER_MODASSIGN,*/
- /*SLANG_OPER_LSHASSIGN,*/
- /*SLANG_OPER_RSHASSIGN,*/
- /*SLANG_OPER_ORASSIGN,*/
- /*SLANG_OPER_XORASSIGN,*/
- /*SLANG_OPER_ANDASSIGN,*/
- case SLANG_OPER_SELECT:
- spaces(indent);
- printf("SLANG_OPER_SELECT n=%d\n", op->num_children);
- assert(op->num_children == 3);
- slang_print_tree(&op->children[0], indent+3);
- spaces(indent);
- printf("?\n");
- slang_print_tree(&op->children[1], indent+3);
- spaces(indent);
- printf(":\n");
- slang_print_tree(&op->children[2], indent+3);
- break;
-
- case SLANG_OPER_LOGICALOR:
- print_binary(op, "||", indent);
- break;
-
- case SLANG_OPER_LOGICALXOR:
- print_binary(op, "^^", indent);
- break;
-
- case SLANG_OPER_LOGICALAND:
- print_binary(op, "&&", indent);
- break;
-
- /*SLANG_OPER_BITOR*/
- /*SLANG_OPER_BITXOR*/
- /*SLANG_OPER_BITAND*/
- case SLANG_OPER_EQUAL:
- print_binary(op, "==", indent);
- break;
-
- case SLANG_OPER_NOTEQUAL:
- print_binary(op, "!=", indent);
- break;
-
- case SLANG_OPER_LESS:
- print_binary(op, "<", indent);
- break;
-
- case SLANG_OPER_GREATER:
- print_binary(op, ">", indent);
- break;
-
- case SLANG_OPER_LESSEQUAL:
- print_binary(op, "<=", indent);
- break;
-
- case SLANG_OPER_GREATEREQUAL:
- print_binary(op, ">=", indent);
- break;
-
- /*SLANG_OPER_LSHIFT*/
- /*SLANG_OPER_RSHIFT*/
- case SLANG_OPER_ADD:
- print_binary(op, "+", indent);
- break;
-
- case SLANG_OPER_SUBTRACT:
- print_binary(op, "-", indent);
- break;
-
- case SLANG_OPER_MULTIPLY:
- print_binary(op, "*", indent);
- break;
-
- case SLANG_OPER_DIVIDE:
- print_binary(op, "/", indent);
- break;
-
- /*SLANG_OPER_MODULUS*/
- case SLANG_OPER_PREINCREMENT:
- spaces(indent);
- printf("PRE++\n");
- slang_print_tree(&op->children[0], indent+3);
- break;
-
- case SLANG_OPER_PREDECREMENT:
- spaces(indent);
- printf("PRE--\n");
- slang_print_tree(&op->children[0], indent+3);
- break;
-
- case SLANG_OPER_PLUS:
- spaces(indent);
- printf("SLANG_OPER_PLUS\n");
- break;
-
- case SLANG_OPER_MINUS:
- spaces(indent);
- printf("SLANG_OPER_MINUS\n");
- break;
-
- /*SLANG_OPER_COMPLEMENT*/
- case SLANG_OPER_NOT:
- spaces(indent);
- printf("NOT\n");
- slang_print_tree(&op->children[0], indent+3);
- break;
-
- case SLANG_OPER_SUBSCRIPT:
- spaces(indent);
- printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n",
- (void *) op->locals,
- (void *) op->locals->outer_scope);
- print_generic(op, NULL, indent+3);
- break;
-
- case SLANG_OPER_CALL:
-#if 0
- slang_function *fun
- = _slang_function_locate(A->space.funcs, oper->a_id,
- oper->children,
- oper->num_children, &A->space, A->atoms);
-#endif
- spaces(indent);
- printf("CALL %s(\n", (char *) op->a_id);
- for (i = 0; i < op->num_children; i++) {
- slang_print_tree(&op->children[i], indent+3);
- if (i + 1 < op->num_children) {
- spaces(indent + 3);
- printf(",\n");
- }
- }
- spaces(indent);
- printf(")\n");
- break;
-
- case SLANG_OPER_METHOD:
- spaces(indent);
- printf("METHOD CALL %s.%s\n", (char *) op->a_obj, (char *) op->a_id);
- break;
-
- case SLANG_OPER_FIELD:
- spaces(indent);
- printf("FIELD %s of\n", (char*) op->a_id);
- slang_print_tree(&op->children[0], indent+3);
- break;
-
- case SLANG_OPER_POSTINCREMENT:
- spaces(indent);
- printf("POST++\n");
- slang_print_tree(&op->children[0], indent+3);
- break;
-
- case SLANG_OPER_POSTDECREMENT:
- spaces(indent);
- printf("POST--\n");
- slang_print_tree(&op->children[0], indent+3);
- break;
-
- default:
- printf("unknown op->type %d\n", (int) op->type);
- }
-
-}
-
-
-
-void
-slang_print_function(const slang_function *f, GLboolean body)
-{
- GLuint i;
-
-#if 0
- if (strcmp((char *) f->header.a_name, "main") != 0)
- return;
-#endif
-
- printf("FUNCTION %s ( scope=%p\n",
- (char *) f->header.a_name, (void *) f->parameters);
-
- for (i = 0; i < f->param_count; i++) {
- print_variable(f->parameters->variables[i], 3);
- }
-
- printf(") param scope = %p\n", (void *) f->parameters);
-
- if (body && f->body)
- slang_print_tree(f->body, 0);
-}
-
-
-
-
-
-const char *
-slang_type_qual_string(slang_type_qualifier q)
-{
- switch (q) {
- case SLANG_QUAL_NONE:
- return "none";
- case SLANG_QUAL_CONST:
- return "const";
- case SLANG_QUAL_ATTRIBUTE:
- return "attribute";
- case SLANG_QUAL_VARYING:
- return "varying";
- case SLANG_QUAL_UNIFORM:
- return "uniform";
- case SLANG_QUAL_OUT:
- return "out";
- case SLANG_QUAL_INOUT:
- return "inout";
- case SLANG_QUAL_FIXEDOUTPUT:
- return "fixedoutput";
- case SLANG_QUAL_FIXEDINPUT:
- return "fixedinputk";
- default:
- return "qual?";
- }
-}
-
-
-static const char *
-slang_type_string(slang_type_specifier_type t)
-{
- switch (t) {
- case SLANG_SPEC_VOID:
- return "void";
- case SLANG_SPEC_BOOL:
- return "bool";
- case SLANG_SPEC_BVEC2:
- return "bvec2";
- case SLANG_SPEC_BVEC3:
- return "bvec3";
- case SLANG_SPEC_BVEC4:
- return "bvec4";
- case SLANG_SPEC_INT:
- return "int";
- case SLANG_SPEC_IVEC2:
- return "ivec2";
- case SLANG_SPEC_IVEC3:
- return "ivec3";
- case SLANG_SPEC_IVEC4:
- return "ivec4";
- case SLANG_SPEC_FLOAT:
- return "float";
- case SLANG_SPEC_VEC2:
- return "vec2";
- case SLANG_SPEC_VEC3:
- return "vec3";
- case SLANG_SPEC_VEC4:
- return "vec4";
- case SLANG_SPEC_MAT2:
- return "mat2";
- case SLANG_SPEC_MAT3:
- return "mat3";
- case SLANG_SPEC_MAT4:
- return "mat4";
- case SLANG_SPEC_SAMPLER_1D:
- return "sampler1D";
- case SLANG_SPEC_SAMPLER_2D:
- return "sampler2D";
- case SLANG_SPEC_SAMPLER_3D:
- return "sampler3D";
- case SLANG_SPEC_SAMPLER_CUBE:
- return "samplerCube";
- case SLANG_SPEC_SAMPLER_1D_SHADOW:
- return "sampler1DShadow";
- case SLANG_SPEC_SAMPLER_2D_SHADOW:
- return "sampler2DShadow";
- case SLANG_SPEC_SAMPLER_RECT:
- return "sampler2DRect";
- case SLANG_SPEC_SAMPLER_RECT_SHADOW:
- return "sampler2DRectShadow";
- case SLANG_SPEC_STRUCT:
- return "struct";
- case SLANG_SPEC_ARRAY:
- return "array";
- default:
- return "type?";
- }
-}
-
-
-static const char *
-slang_fq_type_string(const slang_fully_specified_type *t)
-{
- static char str[1000];
- _mesa_snprintf(str, sizeof(str), "%s %s", slang_type_qual_string(t->qualifier),
- slang_type_string(t->specifier.type));
- return str;
-}
-
-
-void
-slang_print_type(const slang_fully_specified_type *t)
-{
- printf("%s %s", slang_type_qual_string(t->qualifier),
- slang_type_string(t->specifier.type));
-}
-
-
-#if 0
-static char *
-slang_var_string(const slang_variable *v)
-{
- static char str[1000];
- _mesa_snprintf(str, sizeof(str), "%s : %s",
- (char *) v->a_name,
- slang_fq_type_string(&v->type));
- return str;
-}
-#endif
-
-
-void
-slang_print_variable(const slang_variable *v)
-{
- printf("Name: %s\n", (char *) v->a_name);
- printf("Type: %s\n", slang_fq_type_string(&v->type));
-}
-
-
-void
-_slang_print_var_scope(const slang_variable_scope *vars, int indent)
-{
- GLuint i;
-
- spaces(indent);
- printf("Var scope %p %d vars:\n", (void *) vars, vars->num_variables);
- for (i = 0; i < vars->num_variables; i++) {
- spaces(indent + 3);
- printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i));
- }
- spaces(indent + 3);
- printf("outer_scope = %p\n", (void*) vars->outer_scope);
-
- if (vars->outer_scope) {
- /*spaces(indent + 3);*/
- _slang_print_var_scope(vars->outer_scope, indent + 3);
- }
-}
-
-
-
-int
-slang_checksum_tree(const slang_operation *op)
-{
- int s = op->num_children;
- GLuint i;
-
- for (i = 0; i < op->num_children; i++) {
- s += slang_checksum_tree(&op->children[i]);
- }
- return s;
-}
diff --git a/src/mesa/slang/slang_print.h b/src/mesa/slang/slang_print.h
deleted file mode 100644
index 99da3041437..00000000000
--- a/src/mesa/slang/slang_print.h
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-#ifndef SLANG_PRINT
-#define SLANG_PRINT
-
-#include "main/glheader.h"
-#include "slang_compile_function.h"
-#include "slang_compile_operation.h"
-#include "slang_compile_variable.h"
-#include "slang_typeinfo.h"
-
-extern void
-slang_print_function(const slang_function *f, GLboolean body);
-
-extern void
-slang_print_tree(const slang_operation *op, int indent);
-
-extern const char *
-slang_type_qual_string(slang_type_qualifier q);
-
-extern void
-slang_print_type(const slang_fully_specified_type *t);
-
-extern void
-slang_print_variable(const slang_variable *v);
-
-extern void
-_slang_print_var_scope(const slang_variable_scope *s, int indent);
-
-
-extern int
-slang_checksum_tree(const slang_operation *op);
-
-#endif /* SLANG_PRINT */
-
diff --git a/src/mesa/slang/slang_simplify.c b/src/mesa/slang/slang_simplify.c
deleted file mode 100644
index 13b9ca3c877..00000000000
--- a/src/mesa/slang/slang_simplify.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 2005-2008 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.
- */
-
-/**
- * Functions for constant folding, built-in constant lookup, and function
- * call casting.
- */
-
-
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/get.h"
-#include "slang_compile.h"
-#include "slang_codegen.h"
-#include "slang_simplify.h"
-#include "slang_print.h"
-
-
-#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
-#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
-#endif
-#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
-#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
-#endif
-#ifndef GL_MAX_VARYING_VECTORS
-#define GL_MAX_VARYING_VECTORS 0x8DFC
-#endif
-
-
-/**
- * Lookup the value of named constant, such as gl_MaxLights.
- * \return value of constant, or -1 if unknown
- */
-GLint
-_slang_lookup_constant(const char *name)
-{
- struct constant_info {
- const char *Name;
- const GLenum Token;
- };
- static const struct constant_info info[] = {
- { "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES },
- { "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
- { "gl_MaxDrawBuffers", GL_MAX_DRAW_BUFFERS },
- { "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS },
- { "gl_MaxLights", GL_MAX_LIGHTS },
- { "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS },
- { "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS },
- { "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS },
- { "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS },
- { "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS },
- { "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
- { "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS },
-#if FEATURE_es2_glsl
- { "gl_MaxVertexUniformVectors", GL_MAX_VERTEX_UNIFORM_VECTORS },
- { "gl_MaxVaryingVectors", GL_MAX_VARYING_VECTORS },
- { "gl_MaxFragmentUniformVectors", GL_MAX_FRAGMENT_UNIFORM_VECTORS },
-#endif
- { NULL, 0 }
- };
- GLuint i;
-
- for (i = 0; info[i].Name; i++) {
- if (strcmp(info[i].Name, name) == 0) {
- /* found */
- GLint values[16];
- values[0] = -1;
- _mesa_GetIntegerv(info[i].Token, values);
- ASSERT(values[0] >= 0); /* sanity check that glGetFloatv worked */
- return values[0];
- }
- }
- return -1;
-}
-
-
-static slang_operation_type
-literal_type(slang_operation_type t1, slang_operation_type t2)
-{
- if (t1 == SLANG_OPER_LITERAL_FLOAT || t2 == SLANG_OPER_LITERAL_FLOAT)
- return SLANG_OPER_LITERAL_FLOAT;
- else
- return SLANG_OPER_LITERAL_INT;
-}
-
-
-/**
- * Recursively traverse an AST tree, applying simplifications wherever
- * possible.
- * At the least, we do constant folding. We need to do that much so that
- * compile-time expressions can be evaluated for things like array
- * declarations. I.e.: float foo[3 + 5];
- */
-void
-_slang_simplify(slang_operation *oper,
- const slang_name_space * space,
- slang_atom_pool * atoms)
-{
- GLboolean isFloat[4];
- GLboolean isBool[4];
- GLuint i, n;
-
- if (oper->type == SLANG_OPER_IDENTIFIER) {
- /* see if it's a named constant */
- GLint value = _slang_lookup_constant((char *) oper->a_id);
- /*printf("value[%s] = %d\n", (char*) oper->a_id, value);*/
- if (value >= 0) {
- oper->literal[0] =
- oper->literal[1] =
- oper->literal[2] =
- oper->literal[3] = (GLfloat) value;
- oper->type = SLANG_OPER_LITERAL_INT;
- return;
- }
- /* look for user-defined constant */
- {
- slang_variable *var;
- var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
- if (var) {
- if (var->type.qualifier == SLANG_QUAL_CONST &&
- var->initializer &&
- (var->initializer->type == SLANG_OPER_LITERAL_INT ||
- var->initializer->type == SLANG_OPER_LITERAL_FLOAT)) {
- oper->literal[0] = var->initializer->literal[0];
- oper->literal[1] = var->initializer->literal[1];
- oper->literal[2] = var->initializer->literal[2];
- oper->literal[3] = var->initializer->literal[3];
- oper->literal_size = var->initializer->literal_size;
- oper->type = var->initializer->type;
- /*
- printf("value[%s] = %f\n",
- (char*) oper->a_id, oper->literal[0]);
- */
- return;
- }
- }
- }
- }
-
- /* first, simplify children */
- for (i = 0; i < oper->num_children; i++) {
- _slang_simplify(&oper->children[i], space, atoms);
- }
-
- /* examine children */
- n = MIN2(oper->num_children, 4);
- for (i = 0; i < n; i++) {
- isFloat[i] = (oper->children[i].type == SLANG_OPER_LITERAL_FLOAT ||
- oper->children[i].type == SLANG_OPER_LITERAL_INT);
- isBool[i] = (oper->children[i].type == SLANG_OPER_LITERAL_BOOL);
- }
-
- if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
- /* probably simple arithmetic */
- switch (oper->type) {
- case SLANG_OPER_ADD:
- for (i = 0; i < 4; i++) {
- oper->literal[i]
- = oper->children[0].literal[i] + oper->children[1].literal[i];
- }
- oper->literal_size = oper->children[0].literal_size;
- oper->type = literal_type(oper->children[0].type,
- oper->children[1].type);
- slang_operation_destruct(oper); /* frees unused children */
- return;
- case SLANG_OPER_SUBTRACT:
- for (i = 0; i < 4; i++) {
- oper->literal[i]
- = oper->children[0].literal[i] - oper->children[1].literal[i];
- }
- oper->literal_size = oper->children[0].literal_size;
- oper->type = literal_type(oper->children[0].type,
- oper->children[1].type);
- slang_operation_destruct(oper);
- return;
- case SLANG_OPER_MULTIPLY:
- for (i = 0; i < 4; i++) {
- oper->literal[i]
- = oper->children[0].literal[i] * oper->children[1].literal[i];
- }
- oper->literal_size = oper->children[0].literal_size;
- oper->type = literal_type(oper->children[0].type,
- oper->children[1].type);
- slang_operation_destruct(oper);
- return;
- case SLANG_OPER_DIVIDE:
- for (i = 0; i < 4; i++) {
- oper->literal[i]
- = oper->children[0].literal[i] / oper->children[1].literal[i];
- }
- oper->literal_size = oper->children[0].literal_size;
- oper->type = literal_type(oper->children[0].type,
- oper->children[1].type);
- slang_operation_destruct(oper);
- return;
- default:
- ; /* nothing */
- }
- }
-
- if (oper->num_children == 1 && isFloat[0]) {
- switch (oper->type) {
- case SLANG_OPER_MINUS:
- for (i = 0; i < 4; i++) {
- oper->literal[i] = -oper->children[0].literal[i];
- }
- oper->literal_size = oper->children[0].literal_size;
- slang_operation_destruct(oper);
- oper->type = SLANG_OPER_LITERAL_FLOAT;
- return;
- case SLANG_OPER_PLUS:
- COPY_4V(oper->literal, oper->children[0].literal);
- oper->literal_size = oper->children[0].literal_size;
- slang_operation_destruct(oper);
- oper->type = SLANG_OPER_LITERAL_FLOAT;
- return;
- default:
- ; /* nothing */
- }
- }
-
- if (oper->num_children == 2 && isBool[0] && isBool[1]) {
- /* simple boolean expression */
- switch (oper->type) {
- case SLANG_OPER_LOGICALAND:
- for (i = 0; i < 4; i++) {
- const GLint a = oper->children[0].literal[i] ? 1 : 0;
- const GLint b = oper->children[1].literal[i] ? 1 : 0;
- oper->literal[i] = (GLfloat) (a && b);
- }
- oper->literal_size = oper->children[0].literal_size;
- slang_operation_destruct(oper);
- oper->type = SLANG_OPER_LITERAL_BOOL;
- return;
- case SLANG_OPER_LOGICALOR:
- for (i = 0; i < 4; i++) {
- const GLint a = oper->children[0].literal[i] ? 1 : 0;
- const GLint b = oper->children[1].literal[i] ? 1 : 0;
- oper->literal[i] = (GLfloat) (a || b);
- }
- oper->literal_size = oper->children[0].literal_size;
- slang_operation_destruct(oper);
- oper->type = SLANG_OPER_LITERAL_BOOL;
- return;
- case SLANG_OPER_LOGICALXOR:
- for (i = 0; i < 4; i++) {
- const GLint a = oper->children[0].literal[i] ? 1 : 0;
- const GLint b = oper->children[1].literal[i] ? 1 : 0;
- oper->literal[i] = (GLfloat) (a ^ b);
- }
- oper->literal_size = oper->children[0].literal_size;
- slang_operation_destruct(oper);
- oper->type = SLANG_OPER_LITERAL_BOOL;
- return;
- default:
- ; /* nothing */
- }
- }
-
- if (oper->num_children == 4
- && isFloat[0] && isFloat[1] && isFloat[2] && isFloat[3]) {
- /* vec4(flt, flt, flt, flt) constructor */
- if (oper->type == SLANG_OPER_CALL) {
- if (strcmp((char *) oper->a_id, "vec4") == 0) {
- oper->literal[0] = oper->children[0].literal[0];
- oper->literal[1] = oper->children[1].literal[0];
- oper->literal[2] = oper->children[2].literal[0];
- oper->literal[3] = oper->children[3].literal[0];
- oper->literal_size = 4;
- slang_operation_destruct(oper);
- oper->type = SLANG_OPER_LITERAL_FLOAT;
- return;
- }
- }
- }
-
- if (oper->num_children == 3 && isFloat[0] && isFloat[1] && isFloat[2]) {
- /* vec3(flt, flt, flt) constructor */
- if (oper->type == SLANG_OPER_CALL) {
- if (strcmp((char *) oper->a_id, "vec3") == 0) {
- oper->literal[0] = oper->children[0].literal[0];
- oper->literal[1] = oper->children[1].literal[0];
- oper->literal[2] = oper->children[2].literal[0];
- oper->literal[3] = oper->literal[2];
- oper->literal_size = 3;
- slang_operation_destruct(oper);
- oper->type = SLANG_OPER_LITERAL_FLOAT;
- return;
- }
- }
- }
-
- if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
- /* vec2(flt, flt) constructor */
- if (oper->type == SLANG_OPER_CALL) {
- if (strcmp((char *) oper->a_id, "vec2") == 0) {
- oper->literal[0] = oper->children[0].literal[0];
- oper->literal[1] = oper->children[1].literal[0];
- oper->literal[2] = oper->literal[1];
- oper->literal[3] = oper->literal[1];
- oper->literal_size = 2;
- slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
- oper->type = SLANG_OPER_LITERAL_FLOAT;
- assert(oper->num_children == 0);
- return;
- }
- }
- }
-
- if (oper->num_children == 1 && isFloat[0]) {
- /* vec2/3/4(flt, flt) constructor */
- if (oper->type == SLANG_OPER_CALL) {
- const char *func = (const char *) oper->a_id;
- if (strncmp(func, "vec", 3) == 0 && func[3] >= '2' && func[3] <= '4') {
- oper->literal[0] =
- oper->literal[1] =
- oper->literal[2] =
- oper->literal[3] = oper->children[0].literal[0];
- oper->literal_size = func[3] - '0';
- assert(oper->literal_size >= 2);
- assert(oper->literal_size <= 4);
- slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
- oper->type = SLANG_OPER_LITERAL_FLOAT;
- assert(oper->num_children == 0);
- return;
- }
- }
- }
-}
-
-
-
-/**
- * Insert casts to try to adapt actual parameters to formal parameters for a
- * function call when an exact match for the parameter types is not found.
- * Example:
- * void foo(int i, bool b) {}
- * x = foo(3.15, 9);
- * Gets translated into:
- * x = foo(int(3.15), bool(9))
- */
-GLboolean
-_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
- const slang_name_space * space,
- slang_atom_pool * atoms, slang_info_log *log)
-{
- const GLboolean haveRetValue = _slang_function_has_return_value(fun);
- const int numParams = fun->param_count - haveRetValue;
- int i;
- int dbg = 0;
-
- if (dbg)
- printf("Adapt call of %d args to func %s (%d params)\n",
- callOper->num_children, (char*) fun->header.a_name, numParams);
-
- for (i = 0; i < numParams; i++) {
- slang_typeinfo argType;
- slang_variable *paramVar = fun->parameters->variables[i];
-
- /* Get type of arg[i] */
- if (!slang_typeinfo_construct(&argType))
- return GL_FALSE;
- if (!_slang_typeof_operation(&callOper->children[i], space,
- &argType, atoms, log)) {
- slang_typeinfo_destruct(&argType);
- return GL_FALSE;
- }
-
- /* see if arg type matches parameter type */
- if (!slang_type_specifier_equal(&argType.spec,
- &paramVar->type.specifier)) {
- /* need to adapt arg type to match param type */
- const char *constructorName =
- slang_type_specifier_type_to_string(paramVar->type.specifier.type);
- slang_operation *child = slang_operation_new(1);
-
- if (dbg)
- printf("Need to adapt types of arg %d\n", i);
-
- slang_operation_copy(child, &callOper->children[i]);
- child->locals->outer_scope = callOper->children[i].locals;
-
-#if 0
- if (_slang_sizeof_type_specifier(&argType.spec) >
- _slang_sizeof_type_specifier(&paramVar->type.specifier)) {
- }
-#endif
-
- callOper->children[i].type = SLANG_OPER_CALL;
- callOper->children[i].a_id = slang_atom_pool_atom(atoms, constructorName);
- callOper->children[i].num_children = 1;
- callOper->children[i].children = child;
- }
-
- slang_typeinfo_destruct(&argType);
- }
-
- if (dbg) {
- printf("===== New call to %s with cast arguments ===============\n",
- (char*) fun->header.a_name);
- slang_print_tree(callOper, 5);
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Adapt the arguments for a function call to match the parameters of
- * the given function.
- * This is for:
- * 1. converting/casting argument types to match parameters
- * 2. breaking up vector/matrix types into individual components to
- * satisfy constructors.
- */
-GLboolean
-_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
- const slang_name_space * space,
- slang_atom_pool * atoms, slang_info_log *log)
-{
- const GLboolean haveRetValue = _slang_function_has_return_value(fun);
- const int numParams = fun->param_count - haveRetValue;
- int i;
- int dbg = 0;
-
- if (dbg)
- printf("Adapt %d args to %d parameters for %s\n",
- callOper->num_children, numParams, (char *) fun->header.a_name);
-
- /* Only try adapting for constructors */
- if (fun->kind != SLANG_FUNC_CONSTRUCTOR)
- return GL_FALSE;
-
- if (callOper->num_children != numParams) {
- /* number of arguments doesn't match number of parameters */
-
- /* For constructor calls, we can try to unroll vector/matrix args
- * into individual floats/ints and try to match the function params.
- */
- for (i = 0; i < numParams; i++) {
- slang_typeinfo argType;
- GLint argSz, j;
-
- /* Get type of arg[i] */
- if (!slang_typeinfo_construct(&argType))
- return GL_FALSE;
- if (!_slang_typeof_operation(&callOper->children[i], space,
- &argType, atoms, log)) {
- slang_typeinfo_destruct(&argType);
- return GL_FALSE;
- }
-
- /*
- paramSz = _slang_sizeof_type_specifier(&paramVar->type.specifier);
- assert(paramSz == 1);
- */
- argSz = _slang_sizeof_type_specifier(&argType.spec);
- if (argSz > 1) {
- slang_operation origArg;
- /* break up arg[i] into components */
- if (dbg)
- printf("Break up arg %d from 1 to %d elements\n", i, argSz);
-
- slang_operation_construct(&origArg);
- slang_operation_copy(&origArg, &callOper->children[i]);
-
- /* insert argSz-1 new children/args */
- for (j = 0; j < argSz - 1; j++) {
- (void) slang_operation_insert(&callOper->num_children,
- &callOper->children, i);
- }
-
- /* replace arg[i+j] with subscript/index oper */
- for (j = 0; j < argSz; j++) {
- callOper->children[i + j].type = SLANG_OPER_SUBSCRIPT;
- callOper->children[i + j].locals = _slang_variable_scope_new(callOper->locals);
- callOper->children[i + j].num_children = 2;
- callOper->children[i + j].children = slang_operation_new(2);
- slang_operation_copy(&callOper->children[i + j].children[0],
- &origArg);
- callOper->children[i + j].children[1].type
- = SLANG_OPER_LITERAL_INT;
- callOper->children[i + j].children[1].literal[0] = (GLfloat) j;
- }
- }
- }
- }
-
- if (callOper->num_children < (GLuint) numParams) {
- /* still not enough args for all params */
- return GL_FALSE;
- }
- else if (callOper->num_children > (GLuint) numParams) {
- /* now too many arguments */
- /* just truncate */
- callOper->num_children = (GLuint) numParams;
- }
-
- if (dbg) {
- printf("===== New call to %s with adapted arguments ===============\n",
- (char*) fun->header.a_name);
- slang_print_tree(callOper, 5);
- }
-
- return GL_TRUE;
-}
diff --git a/src/mesa/slang/slang_simplify.h b/src/mesa/slang/slang_simplify.h
deleted file mode 100644
index 37fb938d4fb..00000000000
--- a/src/mesa/slang/slang_simplify.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 2005-2008 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 SLANG_SIMPLIFY_H
-#define SLANG_SIMPLIFY_H
-
-
-#include "main/glheader.h"
-#include "slang_compile.h"
-#include "slang_compile_function.h"
-#include "slang_compile_operation.h"
-#include "slang_log.h"
-#include "slang_utility.h"
-
-extern GLint
-_slang_lookup_constant(const char *name);
-
-
-extern void
-_slang_simplify(slang_operation *oper,
- const slang_name_space * space,
- slang_atom_pool * atoms);
-
-
-extern GLboolean
-_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
- const slang_name_space * space,
- slang_atom_pool * atoms, slang_info_log *log);
-
-extern GLboolean
-_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
- const slang_name_space * space,
- slang_atom_pool * atoms, slang_info_log *log);
-
-
-#endif /* SLANG_SIMPLIFY_H */
diff --git a/src/mesa/slang/slang_storage.c b/src/mesa/slang/slang_storage.c
deleted file mode 100644
index 656e15670d3..00000000000
--- a/src/mesa/slang/slang_storage.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-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 slang_storage.c
- * slang variable storage
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_storage.h"
-#include "slang_mem.h"
-
-/* slang_storage_array */
-
-GLboolean
-slang_storage_array_construct(slang_storage_array * arr)
-{
- arr->type = SLANG_STORE_AGGREGATE;
- arr->aggregate = NULL;
- arr->length = 0;
- return GL_TRUE;
-}
-
-GLvoid
-slang_storage_array_destruct(slang_storage_array * arr)
-{
- if (arr->aggregate != NULL) {
- slang_storage_aggregate_destruct(arr->aggregate);
- _slang_free(arr->aggregate);
- }
-}
-
-/* slang_storage_aggregate */
-
-GLboolean
-slang_storage_aggregate_construct(slang_storage_aggregate * agg)
-{
- agg->arrays = NULL;
- agg->count = 0;
- return GL_TRUE;
-}
-
-GLvoid
-slang_storage_aggregate_destruct(slang_storage_aggregate * agg)
-{
- GLuint i;
-
- for (i = 0; i < agg->count; i++)
- slang_storage_array_destruct(agg->arrays + i);
- _slang_free(agg->arrays);
-}
-
-static slang_storage_array *
-slang_storage_aggregate_push_new(slang_storage_aggregate * agg)
-{
- slang_storage_array *arr = NULL;
-
- agg->arrays = (slang_storage_array *)
- _slang_realloc(agg->arrays,
- agg->count * sizeof(slang_storage_array),
- (agg->count + 1) * sizeof(slang_storage_array));
- if (agg->arrays != NULL) {
- arr = agg->arrays + agg->count;
- if (!slang_storage_array_construct(arr))
- return NULL;
- agg->count++;
- }
- return arr;
-}
-
-/* _slang_aggregate_variable() */
-
-static GLboolean
-aggregate_vector(slang_storage_aggregate * agg, slang_storage_type basic_type,
- GLuint row_count)
-{
- slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
- if (arr == NULL)
- return GL_FALSE;
- arr->type = basic_type;
- arr->length = row_count;
- return GL_TRUE;
-}
-
-static GLboolean
-aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type,
- GLuint columns, GLuint rows)
-{
- slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
- if (arr == NULL)
- return GL_FALSE;
- arr->type = SLANG_STORE_AGGREGATE;
- arr->length = columns;
- arr->aggregate = (slang_storage_aggregate *)
- _slang_alloc(sizeof(slang_storage_aggregate));
- if (arr->aggregate == NULL)
- return GL_FALSE;
- if (!slang_storage_aggregate_construct(arr->aggregate)) {
- _slang_free(arr->aggregate);
- arr->aggregate = NULL;
- return GL_FALSE;
- }
- if (!aggregate_vector(arr->aggregate, basic_type, rows))
- return GL_FALSE;
- return GL_TRUE;
-}
-
-
-static GLboolean
-aggregate_variables(slang_storage_aggregate * agg,
- slang_variable_scope * vars, slang_function_scope * funcs,
- slang_struct_scope * structs,
- slang_variable_scope * globals,
- slang_atom_pool * atoms)
-{
- GLuint i;
-
- for (i = 0; i < vars->num_variables; i++)
- if (!_slang_aggregate_variable(agg, &vars->variables[i]->type.specifier,
- vars->variables[i]->array_len, funcs,
- structs, globals, atoms))
- return GL_FALSE;
- return GL_TRUE;
-}
-
-
-GLboolean
-_slang_aggregate_variable(slang_storage_aggregate * agg,
- slang_type_specifier * spec, GLuint array_len,
- slang_function_scope * funcs,
- slang_struct_scope * structs,
- slang_variable_scope * vars,
- slang_atom_pool * atoms)
-{
- switch (spec->type) {
- case SLANG_SPEC_BOOL:
- return aggregate_vector(agg, SLANG_STORE_BOOL, 1);
- case SLANG_SPEC_BVEC2:
- return aggregate_vector(agg, SLANG_STORE_BOOL, 2);
- case SLANG_SPEC_BVEC3:
- return aggregate_vector(agg, SLANG_STORE_BOOL, 3);
- case SLANG_SPEC_BVEC4:
- return aggregate_vector(agg, SLANG_STORE_BOOL, 4);
- case SLANG_SPEC_INT:
- return aggregate_vector(agg, SLANG_STORE_INT, 1);
- case SLANG_SPEC_IVEC2:
- return aggregate_vector(agg, SLANG_STORE_INT, 2);
- case SLANG_SPEC_IVEC3:
- return aggregate_vector(agg, SLANG_STORE_INT, 3);
- case SLANG_SPEC_IVEC4:
- return aggregate_vector(agg, SLANG_STORE_INT, 4);
- case SLANG_SPEC_FLOAT:
- return aggregate_vector(agg, SLANG_STORE_FLOAT, 1);
- case SLANG_SPEC_VEC2:
- return aggregate_vector(agg, SLANG_STORE_FLOAT, 2);
- case SLANG_SPEC_VEC3:
- return aggregate_vector(agg, SLANG_STORE_FLOAT, 3);
- case SLANG_SPEC_VEC4:
- return aggregate_vector(agg, SLANG_STORE_FLOAT, 4);
- case SLANG_SPEC_MAT2:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 2);
- case SLANG_SPEC_MAT3:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 3);
- case SLANG_SPEC_MAT4:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 4);
-
- case SLANG_SPEC_MAT23:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 3);
- case SLANG_SPEC_MAT32:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 2);
- case SLANG_SPEC_MAT24:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 4);
- case SLANG_SPEC_MAT42:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 2);
- case SLANG_SPEC_MAT34:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 4);
- case SLANG_SPEC_MAT43:
- return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 3);
-
- case SLANG_SPEC_SAMPLER_1D:
- case SLANG_SPEC_SAMPLER_2D:
- case SLANG_SPEC_SAMPLER_3D:
- case SLANG_SPEC_SAMPLER_CUBE:
- case SLANG_SPEC_SAMPLER_1D_SHADOW:
- case SLANG_SPEC_SAMPLER_2D_SHADOW:
- case SLANG_SPEC_SAMPLER_RECT:
- case SLANG_SPEC_SAMPLER_RECT_SHADOW:
- case SLANG_SPEC_SAMPLER_1D_ARRAY:
- case SLANG_SPEC_SAMPLER_2D_ARRAY:
- case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
- case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
-
- return aggregate_vector(agg, SLANG_STORE_INT, 1);
- case SLANG_SPEC_STRUCT:
- return aggregate_variables(agg, spec->_struct->fields, funcs, structs,
- vars, atoms);
- case SLANG_SPEC_ARRAY:
- {
- slang_storage_array *arr;
-
- arr = slang_storage_aggregate_push_new(agg);
- if (arr == NULL)
- return GL_FALSE;
- arr->type = SLANG_STORE_AGGREGATE;
- arr->aggregate = (slang_storage_aggregate *)
- _slang_alloc(sizeof(slang_storage_aggregate));
- if (arr->aggregate == NULL)
- return GL_FALSE;
- if (!slang_storage_aggregate_construct(arr->aggregate)) {
- _slang_free(arr->aggregate);
- arr->aggregate = NULL;
- return GL_FALSE;
- }
- if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0,
- funcs, structs, vars, atoms))
- return GL_FALSE;
- arr->length = array_len;
- /* TODO: check if 0 < arr->length <= 65535 */
- }
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-GLuint
-_slang_sizeof_type(slang_storage_type type)
-{
- if (type == SLANG_STORE_AGGREGATE)
- return 0;
- if (type == SLANG_STORE_VEC4)
- return 4 * sizeof(GLfloat);
- return sizeof(GLfloat);
-}
-
-
-GLuint
-_slang_sizeof_aggregate(const slang_storage_aggregate * agg)
-{
- GLuint i, size = 0;
-
- for (i = 0; i < agg->count; i++) {
- slang_storage_array *arr = &agg->arrays[i];
- GLuint element_size;
-
- if (arr->type == SLANG_STORE_AGGREGATE)
- element_size = _slang_sizeof_aggregate(arr->aggregate);
- else
- element_size = _slang_sizeof_type(arr->type);
- size += element_size * arr->length;
- }
- return size;
-}
-
-
-#if 0
-GLboolean
-_slang_flatten_aggregate(slang_storage_aggregate * flat,
- const slang_storage_aggregate * agg)
-{
- GLuint i;
-
- for (i = 0; i < agg->count; i++) {
- GLuint j;
-
- for (j = 0; j < agg->arrays[i].length; j++) {
- if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) {
- if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate))
- return GL_FALSE;
- }
- else {
- GLuint k, count;
- slang_storage_type type;
-
- if (agg->arrays[i].type == SLANG_STORE_VEC4) {
- count = 4;
- type = SLANG_STORE_FLOAT;
- }
- else {
- count = 1;
- type = agg->arrays[i].type;
- }
-
- for (k = 0; k < count; k++) {
- slang_storage_array *arr;
-
- arr = slang_storage_aggregate_push_new(flat);
- if (arr == NULL)
- return GL_FALSE;
- arr->type = type;
- arr->length = 1;
- }
- }
- }
- }
- return GL_TRUE;
-}
-#endif
diff --git a/src/mesa/slang/slang_storage.h b/src/mesa/slang/slang_storage.h
deleted file mode 100644
index 1876a36dd63..00000000000
--- a/src/mesa/slang/slang_storage.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-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 SLANG_STORAGE_H
-#define SLANG_STORAGE_H
-
-#include "slang_compile.h"
-
-
-/*
- * Program variable data storage is kept completely transparent to the
- * front-end compiler. It is up to the back-end how the data is
- * actually allocated. The slang_storage_type enum provides the basic
- * information about how the memory is interpreted. This abstract
- * piece of memory is called a data slot. A data slot of a particular
- * type has a fixed size.
- *
- * For now, only the three basic types are supported, that is bool,
- * int and float. Other built-in types like vector or matrix can
- * easily be decomposed into a series of basic types.
- *
- * If the vec4 module is enabled, 4-component vectors of floats are
- * used when possible. 4x4 matrices are constructed of 4 vec4 slots.
- */
-typedef enum slang_storage_type_
-{
- /* core */
- SLANG_STORE_AGGREGATE,
- SLANG_STORE_BOOL,
- SLANG_STORE_INT,
- SLANG_STORE_FLOAT,
- /* vec4 */
- SLANG_STORE_VEC4
-} slang_storage_type;
-
-
-/**
- * The slang_storage_array structure groups data slots of the same
- * type into an array. This array has a fixed length. Arrays are
- * required to have a size equal to the sum of sizes of its
- * elements. They are also required to support indirect
- * addressing. That is, if B references first data slot in the array,
- * S is the size of the data slot and I is the integral index that is
- * not known at compile time, B+I*S references I-th data slot.
- *
- * This structure is also used to break down built-in data types that
- * are not supported directly. Vectors, like vec3, are constructed
- * from arrays of their basic types. Matrices are formed of an array
- * of column vectors, which are in turn processed as other vectors.
- */
-typedef struct slang_storage_array_
-{
- slang_storage_type type;
- struct slang_storage_aggregate_ *aggregate;
- GLuint length;
-} slang_storage_array;
-
-GLboolean slang_storage_array_construct (slang_storage_array *);
-GLvoid slang_storage_array_destruct (slang_storage_array *);
-
-
-/**
- * The slang_storage_aggregate structure relaxes the indirect
- * addressing requirement for slang_storage_array
- * structure. Aggregates are always accessed statically - its member
- * addresses are well-known at compile time. For example, user-defined
- * types are implemented as aggregates. Aggregates can collect data of
- * a different type.
- */
-typedef struct slang_storage_aggregate_
-{
- slang_storage_array *arrays;
- GLuint count;
-} slang_storage_aggregate;
-
-GLboolean slang_storage_aggregate_construct (slang_storage_aggregate *);
-GLvoid slang_storage_aggregate_destruct (slang_storage_aggregate *);
-
-
-extern GLboolean
-_slang_aggregate_variable(slang_storage_aggregate *agg,
- slang_type_specifier *spec,
- GLuint array_len,
- slang_function_scope *funcs,
- slang_struct_scope *structs,
- slang_variable_scope *vars,
- slang_atom_pool *atoms);
-
-/*
- * Returns the size (in machine units) of the given storage type.
- * It is an error to pass-in SLANG_STORE_AGGREGATE.
- * Returns 0 on error.
- */
-extern GLuint
-_slang_sizeof_type (slang_storage_type);
-
-
-/**
- * Returns total size (in machine units) of the given aggregate.
- * Returns 0 on error.
- */
-extern GLuint
-_slang_sizeof_aggregate (const slang_storage_aggregate *);
-
-
-#if 0
-/**
- * Converts structured aggregate to a flat one, with arrays of generic
- * type being one-element long. Returns GL_TRUE on success. Returns
- * GL_FALSE otherwise.
- */
-extern GLboolean
-_slang_flatten_aggregate (slang_storage_aggregate *,
- const slang_storage_aggregate *);
-
-#endif
-
-#endif /* SLANG_STORAGE_H */
diff --git a/src/mesa/slang/slang_typeinfo.c b/src/mesa/slang/slang_typeinfo.c
deleted file mode 100644
index d039a12e986..00000000000
--- a/src/mesa/slang/slang_typeinfo.c
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-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 slang_typeinfo.c
- * slang type info
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "program/prog_instruction.h"
-#include "slang_typeinfo.h"
-#include "slang_compile.h"
-#include "slang_log.h"
-#include "slang_mem.h"
-
-
-/**
- * Checks if a field selector is a general swizzle (an r-value swizzle
- * with replicated components or an l-value swizzle mask) for a
- * vector. Returns GL_TRUE if this is the case, <swz> is filled with
- * swizzle information. Returns GL_FALSE otherwise.
- */
-GLboolean
-_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz)
-{
- GLuint i;
- GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE;
-
- /* init to undefined.
- * We rely on undefined/nil values to distinguish between
- * regular swizzles and writemasks.
- * For example, the swizzle ".xNNN" is the writemask ".x".
- * That's different than the swizzle ".xxxx".
- */
- for (i = 0; i < 4; i++)
- swz->swizzle[i] = SWIZZLE_NIL;
-
- /* the swizzle can be at most 4-component long */
- swz->num_components = slang_string_length(field);
- if (swz->num_components > 4)
- return GL_FALSE;
-
- for (i = 0; i < swz->num_components; i++) {
- /* mark which swizzle group is used */
- switch (field[i]) {
- case 'x':
- case 'y':
- case 'z':
- case 'w':
- xyzw = GL_TRUE;
- break;
- case 'r':
- case 'g':
- case 'b':
- case 'a':
- rgba = GL_TRUE;
- break;
- case 's':
- case 't':
- case 'p':
- case 'q':
- stpq = GL_TRUE;
- break;
- default:
- return GL_FALSE;
- }
-
- /* collect swizzle component */
- switch (field[i]) {
- case 'x':
- case 'r':
- case 's':
- swz->swizzle[i] = 0;
- break;
- case 'y':
- case 'g':
- case 't':
- swz->swizzle[i] = 1;
- break;
- case 'z':
- case 'b':
- case 'p':
- swz->swizzle[i] = 2;
- break;
- case 'w':
- case 'a':
- case 'q':
- swz->swizzle[i] = 3;
- break;
- }
-
- /* check if the component is valid for given vector's row count */
- if (rows <= swz->swizzle[i])
- return GL_FALSE;
- }
-
- /* only one swizzle group can be used */
- if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-
-
-/**
- * Checks if a general swizzle is an l-value swizzle - these swizzles
- * do not have duplicated fields. Returns GL_TRUE if this is a
- * swizzle mask. Returns GL_FALSE otherwise
- */
-static GLboolean
-_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows)
-{
- GLuint i, c = 0;
-
- /* the swizzle may not be longer than the vector dim */
- if (swz->num_components > rows)
- return GL_FALSE;
-
- /* the swizzle components cannot be duplicated */
- for (i = 0; i < swz->num_components; i++) {
- if ((c & (1 << swz->swizzle[i])) != 0)
- return GL_FALSE;
- c |= 1 << swz->swizzle[i];
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Combines (multiplies) two swizzles to form single swizzle.
- * Example: "vec.wzyx.yx" --> "vec.zw".
- */
-static void
-_slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left,
- const slang_swizzle * right)
-{
- GLuint i;
-
- dst->num_components = right->num_components;
- for (i = 0; i < right->num_components; i++)
- dst->swizzle[i] = left->swizzle[right->swizzle[i]];
-}
-
-
-typedef struct
-{
- const char *name;
- slang_type_specifier_type type;
-} type_specifier_type_name;
-
-static const type_specifier_type_name type_specifier_type_names[] = {
- {"void", SLANG_SPEC_VOID},
- {"bool", SLANG_SPEC_BOOL},
- {"bvec2", SLANG_SPEC_BVEC2},
- {"bvec3", SLANG_SPEC_BVEC3},
- {"bvec4", SLANG_SPEC_BVEC4},
- {"int", SLANG_SPEC_INT},
- {"ivec2", SLANG_SPEC_IVEC2},
- {"ivec3", SLANG_SPEC_IVEC3},
- {"ivec4", SLANG_SPEC_IVEC4},
- {"float", SLANG_SPEC_FLOAT},
- {"vec2", SLANG_SPEC_VEC2},
- {"vec3", SLANG_SPEC_VEC3},
- {"vec4", SLANG_SPEC_VEC4},
- {"mat2", SLANG_SPEC_MAT2},
- {"mat3", SLANG_SPEC_MAT3},
- {"mat4", SLANG_SPEC_MAT4},
- {"mat2x3", SLANG_SPEC_MAT23},
- {"mat3x2", SLANG_SPEC_MAT32},
- {"mat2x4", SLANG_SPEC_MAT24},
- {"mat4x2", SLANG_SPEC_MAT42},
- {"mat3x4", SLANG_SPEC_MAT34},
- {"mat4x3", SLANG_SPEC_MAT43},
- {"sampler1D", SLANG_SPEC_SAMPLER_1D},
- {"sampler2D", SLANG_SPEC_SAMPLER_2D},
- {"sampler3D", SLANG_SPEC_SAMPLER_3D},
- {"samplerCube", SLANG_SPEC_SAMPLER_CUBE},
- {"sampler1DShadow", SLANG_SPEC_SAMPLER_1D_SHADOW},
- {"sampler2DShadow", SLANG_SPEC_SAMPLER_2D_SHADOW},
- {"sampler2DRect", SLANG_SPEC_SAMPLER_RECT},
- {"sampler2DRectShadow", SLANG_SPEC_SAMPLER_RECT_SHADOW},
- {"sampler1DArray", SLANG_SPEC_SAMPLER_1D_ARRAY},
- {"sampler2DArray", SLANG_SPEC_SAMPLER_2D_ARRAY},
- {"sampler1DArrayShadow", SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW},
- {"sampler2DArrayShadow", SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW},
- {NULL, SLANG_SPEC_VOID}
-};
-
-slang_type_specifier_type
-slang_type_specifier_type_from_string(const char *name)
-{
- const type_specifier_type_name *p = type_specifier_type_names;
- while (p->name != NULL) {
- if (slang_string_compare(p->name, name) == 0)
- break;
- p++;
- }
- return p->type;
-}
-
-const char *
-slang_type_specifier_type_to_string(slang_type_specifier_type type)
-{
- const type_specifier_type_name *p = type_specifier_type_names;
- while (p->name != NULL) {
- if (p->type == type)
- break;
- p++;
- }
- return p->name;
-}
-
-/* slang_fully_specified_type */
-
-int
-slang_fully_specified_type_construct(slang_fully_specified_type * type)
-{
- type->qualifier = SLANG_QUAL_NONE;
- slang_type_specifier_ctr(&type->specifier);
- return 1;
-}
-
-void
-slang_fully_specified_type_destruct(slang_fully_specified_type * type)
-{
- slang_type_specifier_dtr(&type->specifier);
-}
-
-int
-slang_fully_specified_type_copy(slang_fully_specified_type * x,
- const slang_fully_specified_type * y)
-{
- slang_fully_specified_type z;
-
- if (!slang_fully_specified_type_construct(&z))
- return 0;
- z.qualifier = y->qualifier;
- z.precision = y->precision;
- z.variant = y->variant;
- z.centroid = y->centroid;
- z.layout = y->layout;
- z.array_len = y->array_len;
- if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) {
- slang_fully_specified_type_destruct(&z);
- return 0;
- }
- slang_fully_specified_type_destruct(x);
- *x = z;
- return 1;
-}
-
-
-/**
- * Test if two fully specified types are compatible. This is a bit
- * looser than testing for equality. We don't check the precision,
- * variant, centroid, etc. information.
- * XXX this may need some tweaking.
- */
-GLboolean
-slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
- const slang_fully_specified_type * y)
-{
- if (!slang_type_specifier_equal(&x->specifier, &y->specifier))
- return GL_FALSE;
-
- if (x->qualifier == SLANG_QUAL_FIXEDINPUT &&
- y->qualifier == SLANG_QUAL_VARYING)
- ; /* ok */
- else if (x->qualifier != y->qualifier)
- return GL_FALSE;
-
- /* Note: don't compare precision, variant, centroid */
-
- /* XXX array length? */
-
- return GL_TRUE;
-}
-
-
-GLvoid
-slang_type_specifier_ctr(slang_type_specifier * self)
-{
- self->type = SLANG_SPEC_VOID;
- self->_struct = NULL;
- self->_array = NULL;
-}
-
-GLvoid
-slang_type_specifier_dtr(slang_type_specifier * self)
-{
- if (self->_struct != NULL) {
- slang_struct_destruct(self->_struct);
- _slang_free(self->_struct);
- }
- if (self->_array != NULL) {
- slang_type_specifier_dtr(self->_array);
- _slang_free(self->_array);
- }
-}
-
-slang_type_specifier *
-slang_type_specifier_new(slang_type_specifier_type type,
- struct slang_struct_ *_struct,
- struct slang_type_specifier_ *_array)
-{
- slang_type_specifier *spec =
- (slang_type_specifier *) _slang_alloc(sizeof(slang_type_specifier));
- if (spec) {
- spec->type = type;
- spec->_struct = _struct;
- spec->_array = _array;
- }
- return spec;
-}
-
-GLboolean
-slang_type_specifier_copy(slang_type_specifier * x,
- const slang_type_specifier * y)
-{
- slang_type_specifier z;
-
- slang_type_specifier_ctr(&z);
- z.type = y->type;
- if (z.type == SLANG_SPEC_STRUCT) {
- z._struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
- if (z._struct == NULL) {
- slang_type_specifier_dtr(&z);
- return GL_FALSE;
- }
- if (!slang_struct_construct(z._struct)) {
- _slang_free(z._struct);
- slang_type_specifier_dtr(&z);
- return GL_FALSE;
- }
- if (!slang_struct_copy(z._struct, y->_struct)) {
- slang_type_specifier_dtr(&z);
- return GL_FALSE;
- }
- }
- else if (z.type == SLANG_SPEC_ARRAY) {
- z._array = (slang_type_specifier *)
- _slang_alloc(sizeof(slang_type_specifier));
- if (z._array == NULL) {
- slang_type_specifier_dtr(&z);
- return GL_FALSE;
- }
- slang_type_specifier_ctr(z._array);
- if (!slang_type_specifier_copy(z._array, y->_array)) {
- slang_type_specifier_dtr(&z);
- return GL_FALSE;
- }
- }
- slang_type_specifier_dtr(x);
- *x = z;
- return GL_TRUE;
-}
-
-
-/**
- * Test if two types are equal.
- */
-GLboolean
-slang_type_specifier_equal(const slang_type_specifier * x,
- const slang_type_specifier * y)
-{
- if (x->type != y->type)
- return GL_FALSE;
- if (x->type == SLANG_SPEC_STRUCT)
- return slang_struct_equal(x->_struct, y->_struct);
- if (x->type == SLANG_SPEC_ARRAY)
- return slang_type_specifier_equal(x->_array, y->_array);
- return GL_TRUE;
-}
-
-
-/**
- * As above, but allow float/int casting.
- */
-GLboolean
-slang_type_specifier_compatible(const slang_type_specifier * x,
- const slang_type_specifier * y)
-{
- /* special case: float == int */
- if (x->type == SLANG_SPEC_INT && y->type == SLANG_SPEC_FLOAT) {
- return GL_TRUE;
- }
- /* XXX may need to add bool/int compatibility, etc */
-
- if (x->type != y->type)
- return GL_FALSE;
- if (x->type == SLANG_SPEC_STRUCT)
- return slang_struct_equal(x->_struct, y->_struct);
- if (x->type == SLANG_SPEC_ARRAY)
- return slang_type_specifier_compatible(x->_array, y->_array);
- return GL_TRUE;
-}
-
-
-GLboolean
-slang_typeinfo_construct(slang_typeinfo * ti)
-{
- memset(ti, 0, sizeof(*ti));
- slang_type_specifier_ctr(&ti->spec);
- ti->array_len = 0;
- return GL_TRUE;
-}
-
-GLvoid
-slang_typeinfo_destruct(slang_typeinfo * ti)
-{
- slang_type_specifier_dtr(&ti->spec);
-}
-
-
-
-/**
- * Determine the return type of a function.
- * \param a_name the function name
- * \param param function parameters (overloading)
- * \param num_params number of parameters to function
- * \param space namespace to search
- * \param spec returns the type
- * \param funFound returns pointer to the function, or NULL if not found.
- * \return GL_TRUE for success, GL_FALSE if failure (bad function name)
- */
-static GLboolean
-_slang_typeof_function(slang_atom a_name,
- slang_operation * params, GLuint num_params,
- const slang_name_space * space,
- slang_type_specifier * spec,
- slang_function **funFound,
- slang_atom_pool *atoms, slang_info_log *log)
-{
- GLboolean error;
-
- *funFound = _slang_function_locate(space->funcs, a_name, params,
- num_params, space, atoms, log, &error);
- if (error)
- return GL_FALSE;
-
- if (!*funFound)
- return GL_TRUE; /* yes, not false */
-
- return slang_type_specifier_copy(spec, &(*funFound)->header.type.specifier);
-}
-
-
-/**
- * Determine the type of a math function.
- * \param name name of the operator, one of +,-,*,/ or unary -
- * \param params array of function parameters
- * \param num_params number of parameters
- * \param space namespace to use
- * \param spec returns the function's type
- * \param atoms atom pool
- * \return GL_TRUE for success, GL_FALSE if failure
- */
-static GLboolean
-typeof_math_call(const char *name, slang_operation *call,
- const slang_name_space * space,
- slang_type_specifier * spec,
- slang_atom_pool * atoms,
- slang_info_log *log)
-{
- if (call->fun) {
- /* we've previously resolved this function call */
- slang_type_specifier_copy(spec, &call->fun->header.type.specifier);
- return GL_TRUE;
- }
- else {
- slang_atom atom;
- slang_function *fun;
-
- /* number of params: */
- assert(call->num_children == 1 || call->num_children == 2);
-
- atom = slang_atom_pool_atom(atoms, name);
- if (!_slang_typeof_function(atom, call->children, call->num_children,
- space, spec, &fun, atoms, log))
- return GL_FALSE;
-
- if (fun) {
- /* Save pointer to save time in future */
- call->fun = fun;
- return GL_TRUE;
- }
- return GL_FALSE;
- }
-}
-
-
-/**
- * Determine the return type of an operation.
- * \param op the operation node
- * \param space the namespace to use
- * \param ti the returned type
- * \param atoms atom pool
- * \return GL_TRUE for success, GL_FALSE if failure
- */
-GLboolean
-_slang_typeof_operation(slang_operation * op,
- const slang_name_space * space,
- slang_typeinfo * ti,
- slang_atom_pool * atoms,
- slang_info_log *log)
-{
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
-
- switch (op->type) {
- case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
- case SLANG_OPER_BLOCK_NEW_SCOPE:
- case SLANG_OPER_ASM:
- case SLANG_OPER_BREAK:
- case SLANG_OPER_CONTINUE:
- case SLANG_OPER_DISCARD:
- case SLANG_OPER_RETURN:
- case SLANG_OPER_IF:
- case SLANG_OPER_WHILE:
- case SLANG_OPER_DO:
- case SLANG_OPER_FOR:
- case SLANG_OPER_VOID:
- ti->spec.type = SLANG_SPEC_VOID;
- break;
- case SLANG_OPER_EXPRESSION:
- case SLANG_OPER_ASSIGN:
- case SLANG_OPER_ADDASSIGN:
- case SLANG_OPER_SUBASSIGN:
- case SLANG_OPER_MULASSIGN:
- case SLANG_OPER_DIVASSIGN:
- case SLANG_OPER_PREINCREMENT:
- case SLANG_OPER_PREDECREMENT:
- if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
- return GL_FALSE;
- break;
- case SLANG_OPER_LITERAL_BOOL:
- if (op->literal_size == 1)
- ti->spec.type = SLANG_SPEC_BOOL;
- else if (op->literal_size == 2)
- ti->spec.type = SLANG_SPEC_BVEC2;
- else if (op->literal_size == 3)
- ti->spec.type = SLANG_SPEC_BVEC3;
- else if (op->literal_size == 4)
- ti->spec.type = SLANG_SPEC_BVEC4;
- else {
- _mesa_problem(NULL,
- "Unexpected bool literal_size %d in _slang_typeof_operation()",
- op->literal_size);
- ti->spec.type = SLANG_SPEC_BOOL;
- }
- break;
- case SLANG_OPER_LOGICALOR:
- case SLANG_OPER_LOGICALXOR:
- case SLANG_OPER_LOGICALAND:
- case SLANG_OPER_EQUAL:
- case SLANG_OPER_NOTEQUAL:
- case SLANG_OPER_LESS:
- case SLANG_OPER_GREATER:
- case SLANG_OPER_LESSEQUAL:
- case SLANG_OPER_GREATEREQUAL:
- case SLANG_OPER_NOT:
- ti->spec.type = SLANG_SPEC_BOOL;
- break;
- case SLANG_OPER_LITERAL_INT:
- if (op->literal_size == 1)
- ti->spec.type = SLANG_SPEC_INT;
- else if (op->literal_size == 2)
- ti->spec.type = SLANG_SPEC_IVEC2;
- else if (op->literal_size == 3)
- ti->spec.type = SLANG_SPEC_IVEC3;
- else if (op->literal_size == 4)
- ti->spec.type = SLANG_SPEC_IVEC4;
- else {
- _mesa_problem(NULL,
- "Unexpected int literal_size %d in _slang_typeof_operation()",
- op->literal_size);
- ti->spec.type = SLANG_SPEC_INT;
- }
- break;
- case SLANG_OPER_LITERAL_FLOAT:
- if (op->literal_size == 1)
- ti->spec.type = SLANG_SPEC_FLOAT;
- else if (op->literal_size == 2)
- ti->spec.type = SLANG_SPEC_VEC2;
- else if (op->literal_size == 3)
- ti->spec.type = SLANG_SPEC_VEC3;
- else if (op->literal_size == 4)
- ti->spec.type = SLANG_SPEC_VEC4;
- else {
- _mesa_problem(NULL,
- "Unexpected float literal_size %d in _slang_typeof_operation()",
- op->literal_size);
- ti->spec.type = SLANG_SPEC_FLOAT;
- }
- break;
- case SLANG_OPER_IDENTIFIER:
- case SLANG_OPER_VARIABLE_DECL:
- {
- slang_variable *var;
- var = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
- if (!var) {
- slang_info_log_error(log, "undefined variable '%s'",
- (char *) op->a_id);
- return GL_FALSE;
- }
- if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) {
- slang_info_log_memory(log);
- return GL_FALSE;
- }
- ti->can_be_referenced = GL_TRUE;
- if (var->type.specifier.type == SLANG_SPEC_ARRAY &&
- var->type.array_len >= 1) {
- /* the datatype is an array, ex: float[3] x; */
- ti->array_len = var->type.array_len;
- }
- else {
- /* the variable is an array, ex: float x[3]; */
- ti->array_len = var->array_len;
- }
- }
- break;
- case SLANG_OPER_SEQUENCE:
- /* TODO: check [0] and [1] if they match */
- if (!_slang_typeof_operation(&op->children[1], space, ti, atoms, log)) {
- return GL_FALSE;
- }
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
- break;
- /*case SLANG_OPER_MODASSIGN: */
- /*case SLANG_OPER_LSHASSIGN: */
- /*case SLANG_OPER_RSHASSIGN: */
- /*case SLANG_OPER_ORASSIGN: */
- /*case SLANG_OPER_XORASSIGN: */
- /*case SLANG_OPER_ANDASSIGN: */
- case SLANG_OPER_SELECT:
- /* TODO: check [1] and [2] if they match */
- if (!_slang_typeof_operation(&op->children[1], space, ti, atoms, log)) {
- return GL_FALSE;
- }
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
- break;
- /*case SLANG_OPER_BITOR: */
- /*case SLANG_OPER_BITXOR: */
- /*case SLANG_OPER_BITAND: */
- /*case SLANG_OPER_LSHIFT: */
- /*case SLANG_OPER_RSHIFT: */
- case SLANG_OPER_ADD:
- assert(op->num_children == 2);
- if (!typeof_math_call("+", op, space, &ti->spec, atoms, log))
- return GL_FALSE;
- break;
- case SLANG_OPER_SUBTRACT:
- assert(op->num_children == 2);
- if (!typeof_math_call("-", op, space, &ti->spec, atoms, log))
- return GL_FALSE;
- break;
- case SLANG_OPER_MULTIPLY:
- assert(op->num_children == 2);
- if (!typeof_math_call("*", op, space, &ti->spec, atoms, log))
- return GL_FALSE;
- break;
- case SLANG_OPER_DIVIDE:
- assert(op->num_children == 2);
- if (!typeof_math_call("/", op, space, &ti->spec, atoms, log))
- return GL_FALSE;
- break;
- /*case SLANG_OPER_MODULUS: */
- case SLANG_OPER_PLUS:
- if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
- return GL_FALSE;
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
- break;
- case SLANG_OPER_MINUS:
- assert(op->num_children == 1);
- if (!typeof_math_call("-", op, space, &ti->spec, atoms, log))
- return GL_FALSE;
- break;
- /*case SLANG_OPER_COMPLEMENT: */
- case SLANG_OPER_SUBSCRIPT:
- {
- slang_typeinfo _ti;
-
- if (!slang_typeinfo_construct(&_ti))
- return GL_FALSE;
- if (!_slang_typeof_operation(op->children, space, &_ti, atoms, log)) {
- slang_typeinfo_destruct(&_ti);
- return GL_FALSE;
- }
- ti->can_be_referenced = _ti.can_be_referenced;
- if (_ti.spec.type == SLANG_SPEC_ARRAY) {
- if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) {
- slang_typeinfo_destruct(&_ti);
- return GL_FALSE;
- }
- }
- else {
- if (!_slang_type_is_vector(_ti.spec.type)
- && !_slang_type_is_matrix(_ti.spec.type)) {
- slang_typeinfo_destruct(&_ti);
- slang_info_log_error(log, "cannot index a non-array type");
- return GL_FALSE;
- }
- ti->spec.type = _slang_type_base(_ti.spec.type);
- }
- slang_typeinfo_destruct(&_ti);
- }
- break;
- case SLANG_OPER_CALL:
- if (op->array_constructor) {
- /* build array typeinfo */
- ti->spec.type = SLANG_SPEC_ARRAY;
- ti->spec._array = (slang_type_specifier *)
- _slang_alloc(sizeof(slang_type_specifier));
- slang_type_specifier_ctr(ti->spec._array);
-
- ti->spec._array->type =
- slang_type_specifier_type_from_string((char *) op->a_id);
- ti->array_len = op->num_children;
- }
- else if (op->fun) {
- /* we've resolved this call before */
- slang_type_specifier_copy(&ti->spec, &op->fun->header.type.specifier);
- }
- else {
- slang_function *fun;
- if (!_slang_typeof_function(op->a_id, op->children, op->num_children,
- space, &ti->spec, &fun, atoms, log))
- return GL_FALSE;
- if (fun) {
- /* save result for future use */
- op->fun = fun;
- }
- else {
- slang_struct *s =
- slang_struct_scope_find(space->structs, op->a_id, GL_TRUE);
- if (s) {
- /* struct initializer */
- ti->spec.type = SLANG_SPEC_STRUCT;
- ti->spec._struct =
- (slang_struct *) _slang_alloc(sizeof(slang_struct));
- if (ti->spec._struct == NULL)
- return GL_FALSE;
- if (!slang_struct_construct(ti->spec._struct)) {
- _slang_free(ti->spec._struct);
- ti->spec._struct = NULL;
- return GL_FALSE;
- }
- if (!slang_struct_copy(ti->spec._struct, s))
- return GL_FALSE;
- }
- else {
- /* float, int, vec4, mat3, etc. constructor? */
- const char *name;
- slang_type_specifier_type type;
-
- name = slang_atom_pool_id(atoms, op->a_id);
- type = slang_type_specifier_type_from_string(name);
- if (type == SLANG_SPEC_VOID) {
- slang_info_log_error(log, "undefined function '%s'", name);
- return GL_FALSE;
- }
- ti->spec.type = type;
- }
- }
- }
- break;
- case SLANG_OPER_METHOD:
- /* at this time, GLSL 1.20 only has one method: array.length()
- * which returns an integer.
- */
- ti->spec.type = SLANG_SPEC_INT;
- break;
- case SLANG_OPER_FIELD:
- {
- slang_typeinfo _ti;
-
- if (!slang_typeinfo_construct(&_ti))
- return GL_FALSE;
- if (!_slang_typeof_operation(op->children, space, &_ti, atoms, log)) {
- slang_typeinfo_destruct(&_ti);
- return GL_FALSE;
- }
- if (_ti.spec.type == SLANG_SPEC_STRUCT) {
- slang_variable *field;
-
- field = _slang_variable_locate(_ti.spec._struct->fields, op->a_id,
- GL_FALSE);
- if (field == NULL) {
- slang_typeinfo_destruct(&_ti);
- return GL_FALSE;
- }
- if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) {
- slang_typeinfo_destruct(&_ti);
- return GL_FALSE;
- }
- ti->can_be_referenced = _ti.can_be_referenced;
- ti->array_len = field->array_len;
- }
- else {
- GLuint rows;
- const char *swizzle;
- slang_type_specifier_type base;
-
- /* determine the swizzle of the field expression */
- if (!_slang_type_is_vector(_ti.spec.type)) {
- slang_typeinfo_destruct(&_ti);
- slang_info_log_error(log, "Can't swizzle scalar expression");
- return GL_FALSE;
- }
- rows = _slang_type_dim(_ti.spec.type);
- swizzle = slang_atom_pool_id(atoms, op->a_id);
- if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) {
- slang_typeinfo_destruct(&_ti);
- slang_info_log_error(log, "bad swizzle '%s'", swizzle);
- return GL_FALSE;
- }
- ti->is_swizzled = GL_TRUE;
- ti->can_be_referenced = _ti.can_be_referenced
- && _slang_is_swizzle_mask(&ti->swz, rows);
- if (_ti.is_swizzled) {
- slang_swizzle swz;
-
- /* swizzle the swizzle */
- _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz);
- ti->swz = swz;
- }
- base = _slang_type_base(_ti.spec.type);
- switch (ti->swz.num_components) {
- case 1:
- ti->spec.type = base;
- break;
- case 2:
- switch (base) {
- case SLANG_SPEC_FLOAT:
- ti->spec.type = SLANG_SPEC_VEC2;
- break;
- case SLANG_SPEC_INT:
- ti->spec.type = SLANG_SPEC_IVEC2;
- break;
- case SLANG_SPEC_BOOL:
- ti->spec.type = SLANG_SPEC_BVEC2;
- break;
- default:
- break;
- }
- break;
- case 3:
- switch (base) {
- case SLANG_SPEC_FLOAT:
- ti->spec.type = SLANG_SPEC_VEC3;
- break;
- case SLANG_SPEC_INT:
- ti->spec.type = SLANG_SPEC_IVEC3;
- break;
- case SLANG_SPEC_BOOL:
- ti->spec.type = SLANG_SPEC_BVEC3;
- break;
- default:
- break;
- }
- break;
- case 4:
- switch (base) {
- case SLANG_SPEC_FLOAT:
- ti->spec.type = SLANG_SPEC_VEC4;
- break;
- case SLANG_SPEC_INT:
- ti->spec.type = SLANG_SPEC_IVEC4;
- break;
- case SLANG_SPEC_BOOL:
- ti->spec.type = SLANG_SPEC_BVEC4;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- slang_typeinfo_destruct(&_ti);
- }
- break;
- case SLANG_OPER_POSTINCREMENT:
- case SLANG_OPER_POSTDECREMENT:
- if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
- return GL_FALSE;
- ti->can_be_referenced = GL_FALSE;
- ti->is_swizzled = GL_FALSE;
- break;
- default:
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Determine if a type is a matrix.
- * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
- */
-GLboolean
-_slang_type_is_matrix(slang_type_specifier_type ty)
-{
- switch (ty) {
- case SLANG_SPEC_MAT2:
- case SLANG_SPEC_MAT3:
- case SLANG_SPEC_MAT4:
- case SLANG_SPEC_MAT23:
- case SLANG_SPEC_MAT32:
- case SLANG_SPEC_MAT24:
- case SLANG_SPEC_MAT42:
- case SLANG_SPEC_MAT34:
- case SLANG_SPEC_MAT43:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Determine if a type is a vector.
- * \return GL_TRUE if is a vector, GL_FALSE otherwise.
- */
-GLboolean
-_slang_type_is_vector(slang_type_specifier_type ty)
-{
- switch (ty) {
- case SLANG_SPEC_VEC2:
- case SLANG_SPEC_VEC3:
- case SLANG_SPEC_VEC4:
- case SLANG_SPEC_IVEC2:
- case SLANG_SPEC_IVEC3:
- case SLANG_SPEC_IVEC4:
- case SLANG_SPEC_BVEC2:
- case SLANG_SPEC_BVEC3:
- case SLANG_SPEC_BVEC4:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Determine if a type is a float, float vector or float matrix.
- * \return GL_TRUE if so, GL_FALSE otherwise
- */
-GLboolean
-_slang_type_is_float_vec_mat(slang_type_specifier_type ty)
-{
- switch (ty) {
- case SLANG_SPEC_FLOAT:
- case SLANG_SPEC_VEC2:
- case SLANG_SPEC_VEC3:
- case SLANG_SPEC_VEC4:
- case SLANG_SPEC_MAT2:
- case SLANG_SPEC_MAT3:
- case SLANG_SPEC_MAT4:
- case SLANG_SPEC_MAT23:
- case SLANG_SPEC_MAT32:
- case SLANG_SPEC_MAT24:
- case SLANG_SPEC_MAT42:
- case SLANG_SPEC_MAT34:
- case SLANG_SPEC_MAT43:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Given a vector type, return the type of the vector's elements.
- * For a matrix, return the type of the columns.
- */
-slang_type_specifier_type
-_slang_type_base(slang_type_specifier_type ty)
-{
- switch (ty) {
- case SLANG_SPEC_FLOAT:
- case SLANG_SPEC_VEC2:
- case SLANG_SPEC_VEC3:
- case SLANG_SPEC_VEC4:
- return SLANG_SPEC_FLOAT;
- case SLANG_SPEC_INT:
- case SLANG_SPEC_IVEC2:
- case SLANG_SPEC_IVEC3:
- case SLANG_SPEC_IVEC4:
- return SLANG_SPEC_INT;
- case SLANG_SPEC_BOOL:
- case SLANG_SPEC_BVEC2:
- case SLANG_SPEC_BVEC3:
- case SLANG_SPEC_BVEC4:
- return SLANG_SPEC_BOOL;
- case SLANG_SPEC_MAT2:
- return SLANG_SPEC_VEC2;
- case SLANG_SPEC_MAT3:
- return SLANG_SPEC_VEC3;
- case SLANG_SPEC_MAT4:
- return SLANG_SPEC_VEC4;
- case SLANG_SPEC_MAT23:
- return SLANG_SPEC_VEC3;
- case SLANG_SPEC_MAT32:
- return SLANG_SPEC_VEC2;
- case SLANG_SPEC_MAT24:
- return SLANG_SPEC_VEC4;
- case SLANG_SPEC_MAT42:
- return SLANG_SPEC_VEC2;
- case SLANG_SPEC_MAT34:
- return SLANG_SPEC_VEC4;
- case SLANG_SPEC_MAT43:
- return SLANG_SPEC_VEC3;
- default:
- return SLANG_SPEC_VOID;
- }
-}
-
-
-/**
- * Return the dimensionality of a vector, or for a matrix, return number
- * of columns.
- */
-GLuint
-_slang_type_dim(slang_type_specifier_type ty)
-{
- switch (ty) {
- case SLANG_SPEC_FLOAT:
- case SLANG_SPEC_INT:
- case SLANG_SPEC_BOOL:
- return 1;
- case SLANG_SPEC_VEC2:
- case SLANG_SPEC_IVEC2:
- case SLANG_SPEC_BVEC2:
- case SLANG_SPEC_MAT2:
- return 2;
- case SLANG_SPEC_VEC3:
- case SLANG_SPEC_IVEC3:
- case SLANG_SPEC_BVEC3:
- case SLANG_SPEC_MAT3:
- return 3;
- case SLANG_SPEC_VEC4:
- case SLANG_SPEC_IVEC4:
- case SLANG_SPEC_BVEC4:
- case SLANG_SPEC_MAT4:
- return 4;
-
- case SLANG_SPEC_MAT23:
- return 2;
- case SLANG_SPEC_MAT32:
- return 3;
- case SLANG_SPEC_MAT24:
- return 2;
- case SLANG_SPEC_MAT42:
- return 4;
- case SLANG_SPEC_MAT34:
- return 3;
- case SLANG_SPEC_MAT43:
- return 4;
-
- default:
- return 0;
- }
-}
-
-
-/**
- * Return the GL_* type that corresponds to a SLANG_SPEC_* type.
- */
-GLenum
-_slang_gltype_from_specifier(const slang_type_specifier *type)
-{
- switch (type->type) {
- case SLANG_SPEC_BOOL:
- return GL_BOOL;
- case SLANG_SPEC_BVEC2:
- return GL_BOOL_VEC2;
- case SLANG_SPEC_BVEC3:
- return GL_BOOL_VEC3;
- case SLANG_SPEC_BVEC4:
- return GL_BOOL_VEC4;
- case SLANG_SPEC_INT:
- return GL_INT;
- case SLANG_SPEC_IVEC2:
- return GL_INT_VEC2;
- case SLANG_SPEC_IVEC3:
- return GL_INT_VEC3;
- case SLANG_SPEC_IVEC4:
- return GL_INT_VEC4;
- case SLANG_SPEC_FLOAT:
- return GL_FLOAT;
- case SLANG_SPEC_VEC2:
- return GL_FLOAT_VEC2;
- case SLANG_SPEC_VEC3:
- return GL_FLOAT_VEC3;
- case SLANG_SPEC_VEC4:
- return GL_FLOAT_VEC4;
- case SLANG_SPEC_MAT2:
- return GL_FLOAT_MAT2;
- case SLANG_SPEC_MAT3:
- return GL_FLOAT_MAT3;
- case SLANG_SPEC_MAT4:
- return GL_FLOAT_MAT4;
- case SLANG_SPEC_MAT23:
- return GL_FLOAT_MAT2x3;
- case SLANG_SPEC_MAT32:
- return GL_FLOAT_MAT3x2;
- case SLANG_SPEC_MAT24:
- return GL_FLOAT_MAT2x4;
- case SLANG_SPEC_MAT42:
- return GL_FLOAT_MAT4x2;
- case SLANG_SPEC_MAT34:
- return GL_FLOAT_MAT3x4;
- case SLANG_SPEC_MAT43:
- return GL_FLOAT_MAT4x3;
- case SLANG_SPEC_SAMPLER_1D:
- return GL_SAMPLER_1D;
- case SLANG_SPEC_SAMPLER_2D:
- return GL_SAMPLER_2D;
- case SLANG_SPEC_SAMPLER_3D:
- return GL_SAMPLER_3D;
- case SLANG_SPEC_SAMPLER_CUBE:
- return GL_SAMPLER_CUBE;
- case SLANG_SPEC_SAMPLER_1D_SHADOW:
- return GL_SAMPLER_1D_SHADOW;
- case SLANG_SPEC_SAMPLER_2D_SHADOW:
- return GL_SAMPLER_2D_SHADOW;
- case SLANG_SPEC_SAMPLER_RECT:
- return GL_SAMPLER_2D_RECT_ARB;
- case SLANG_SPEC_SAMPLER_RECT_SHADOW:
- return GL_SAMPLER_2D_RECT_SHADOW_ARB;
- case SLANG_SPEC_SAMPLER_1D_ARRAY:
- return GL_SAMPLER_1D_ARRAY_EXT;
- case SLANG_SPEC_SAMPLER_2D_ARRAY:
- return GL_SAMPLER_2D_ARRAY_EXT;
- case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
- return GL_SAMPLER_1D_ARRAY_SHADOW_EXT;
- case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
- return GL_SAMPLER_2D_ARRAY_SHADOW_EXT;
- case SLANG_SPEC_ARRAY:
- return _slang_gltype_from_specifier(type->_array);
- case SLANG_SPEC_STRUCT:
- /* fall-through */
- default:
- return GL_NONE;
- }
-}
-
diff --git a/src/mesa/slang/slang_typeinfo.h b/src/mesa/slang/slang_typeinfo.h
deleted file mode 100644
index 2251b063253..00000000000
--- a/src/mesa/slang/slang_typeinfo.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-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 SLANG_TYPEINFO_H
-#define SLANG_TYPEINFO_H 1
-
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "slang_log.h"
-#include "slang_utility.h"
-#include "slang_vartable.h"
-
-
-struct slang_operation_;
-
-struct slang_name_space_;
-
-
-
-/**
- * Holds complete information about vector swizzle - the <swizzle>
- * array contains vector component source indices, where 0 is "x", 1
- * is "y", 2 is "z" and 3 is "w".
- * Example: "xwz" --> { 3, { 0, 3, 2, not used } }.
- */
-typedef struct slang_swizzle_
-{
- GLuint num_components;
- GLuint swizzle[4];
-} slang_swizzle;
-
-extern GLboolean
-_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz);
-
-
-typedef enum slang_type_variant_
-{
- SLANG_VARIANT, /* the default */
- SLANG_INVARIANT /* indicates the "invariant" keyword */
-} slang_type_variant;
-
-
-typedef enum slang_type_centroid_
-{
- SLANG_CENTER, /* the default */
- SLANG_CENTROID /* indicates the "centroid" keyword */
-} slang_type_centroid;
-
-
-/**
- * These only apply to gl_FragCoord, but other layout qualifiers may
- * appear in the future.
- */
-typedef enum slang_layout_qualifier_
-{
- SLANG_LAYOUT_NONE = 0x0,
- SLANG_LAYOUT_UPPER_LEFT_BIT = 0x1,
- SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT = 0x2
-} slang_layout_qualifier;
-
-
-typedef enum slang_type_qualifier_
-{
- SLANG_QUAL_NONE,
- SLANG_QUAL_CONST,
- SLANG_QUAL_ATTRIBUTE,
- SLANG_QUAL_VARYING,
- SLANG_QUAL_UNIFORM,
- SLANG_QUAL_OUT,
- SLANG_QUAL_INOUT,
- SLANG_QUAL_FIXEDOUTPUT, /* internal */
- SLANG_QUAL_FIXEDINPUT /* internal */
-} slang_type_qualifier;
-
-typedef enum slang_varying_kind_
-{
- SLANG_VARYING_IN,
- SLANG_VARYING_OUT,
-} slang_varying_kind;
-
-typedef enum slang_type_precision_
-{
- SLANG_PREC_DEFAULT,
- SLANG_PREC_LOW,
- SLANG_PREC_MEDIUM,
- SLANG_PREC_HIGH
-} slang_type_precision;
-
-
-/**
- * The basic shading language types (float, vec4, mat3, etc)
- */
-typedef enum slang_type_specifier_type_
-{
- SLANG_SPEC_VOID,
- SLANG_SPEC_BOOL,
- SLANG_SPEC_BVEC2,
- SLANG_SPEC_BVEC3,
- SLANG_SPEC_BVEC4,
- SLANG_SPEC_INT,
- SLANG_SPEC_IVEC2,
- SLANG_SPEC_IVEC3,
- SLANG_SPEC_IVEC4,
- SLANG_SPEC_FLOAT,
- SLANG_SPEC_VEC2,
- SLANG_SPEC_VEC3,
- SLANG_SPEC_VEC4,
- SLANG_SPEC_MAT2,
- SLANG_SPEC_MAT3,
- SLANG_SPEC_MAT4,
- SLANG_SPEC_MAT23,
- SLANG_SPEC_MAT32,
- SLANG_SPEC_MAT24,
- SLANG_SPEC_MAT42,
- SLANG_SPEC_MAT34,
- SLANG_SPEC_MAT43,
- SLANG_SPEC_SAMPLER_1D,
- SLANG_SPEC_SAMPLER_2D,
- SLANG_SPEC_SAMPLER_3D,
- SLANG_SPEC_SAMPLER_CUBE,
- SLANG_SPEC_SAMPLER_RECT,
- SLANG_SPEC_SAMPLER_1D_SHADOW,
- SLANG_SPEC_SAMPLER_2D_SHADOW,
- SLANG_SPEC_SAMPLER_RECT_SHADOW,
- SLANG_SPEC_SAMPLER_1D_ARRAY,
- SLANG_SPEC_SAMPLER_2D_ARRAY,
- SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW,
- SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW,
- SLANG_SPEC_STRUCT,
- SLANG_SPEC_ARRAY
-} slang_type_specifier_type;
-
-
-extern slang_type_specifier_type
-slang_type_specifier_type_from_string(const char *);
-
-extern const char *
-slang_type_specifier_type_to_string(slang_type_specifier_type);
-
-
-/**
- * Describes more sophisticated types, like structs and arrays.
- */
-typedef struct slang_type_specifier_
-{
- slang_type_specifier_type type;
- struct slang_struct_ *_struct; /**< if type == SLANG_SPEC_STRUCT */
- struct slang_type_specifier_ *_array; /**< if type == SLANG_SPEC_ARRAY */
-} slang_type_specifier;
-
-
-extern GLvoid
-slang_type_specifier_ctr(slang_type_specifier *);
-
-extern GLvoid
-slang_type_specifier_dtr(slang_type_specifier *);
-
-extern slang_type_specifier *
-slang_type_specifier_new(slang_type_specifier_type type,
- struct slang_struct_ *_struct,
- struct slang_type_specifier_ *_array);
-
-
-extern GLboolean
-slang_type_specifier_copy(slang_type_specifier *, const slang_type_specifier *);
-
-extern GLboolean
-slang_type_specifier_equal(const slang_type_specifier *,
- const slang_type_specifier *);
-
-
-extern GLboolean
-slang_type_specifier_compatible(const slang_type_specifier *x,
- const slang_type_specifier *y);
-
-
-typedef struct slang_fully_specified_type_
-{
- slang_type_qualifier qualifier;
- slang_type_specifier specifier;
- slang_type_precision precision;
- slang_type_variant variant;
- slang_type_centroid centroid;
- slang_layout_qualifier layout;
- GLint array_len; /**< -1 if not an array type */
- slang_varying_kind varying_kind;
-} slang_fully_specified_type;
-
-extern int
-slang_fully_specified_type_construct(slang_fully_specified_type *);
-
-extern void
-slang_fully_specified_type_destruct(slang_fully_specified_type *);
-
-extern int
-slang_fully_specified_type_copy(slang_fully_specified_type *,
- const slang_fully_specified_type *);
-
-GLboolean
-slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
- const slang_fully_specified_type * y);
-
-
-typedef struct slang_typeinfo_
-{
- GLboolean can_be_referenced;
- GLboolean is_swizzled;
- slang_swizzle swz;
- slang_type_specifier spec;
- GLuint array_len;
-} slang_typeinfo;
-
-extern GLboolean
-slang_typeinfo_construct(slang_typeinfo *);
-
-extern GLvoid
-slang_typeinfo_destruct(slang_typeinfo *);
-
-
-extern GLboolean
-_slang_typeof_operation(struct slang_operation_ *,
- const struct slang_name_space_ *,
- slang_typeinfo *, slang_atom_pool *,
- slang_info_log *log);
-
-extern GLboolean
-_slang_type_is_matrix(slang_type_specifier_type);
-
-extern GLboolean
-_slang_type_is_vector(slang_type_specifier_type);
-
-extern GLboolean
-_slang_type_is_float_vec_mat(slang_type_specifier_type);
-
-extern slang_type_specifier_type
-_slang_type_base(slang_type_specifier_type);
-
-extern GLuint
-_slang_type_dim(slang_type_specifier_type);
-
-extern GLenum
-_slang_gltype_from_specifier(const slang_type_specifier *type);
-
-#endif
diff --git a/src/mesa/slang/slang_utility.c b/src/mesa/slang/slang_utility.c
deleted file mode 100644
index c1d57409a43..00000000000
--- a/src/mesa/slang/slang_utility.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-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 slang_utility.c
- * slang utilities
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_utility.h"
-#include "slang_mem.h"
-
-char *
-slang_string_concat (char *dst, const char *src)
-{
- return strcpy (dst + strlen (dst), src);
-}
-
-
-/* slang_string */
-
-GLvoid
-slang_string_init (slang_string *self)
-{
- self->data = NULL;
- self->capacity = 0;
- self->length = 0;
- self->fail = GL_FALSE;
-}
-
-GLvoid
-slang_string_free (slang_string *self)
-{
- if (self->data != NULL)
- free(self->data);
-}
-
-GLvoid
-slang_string_reset (slang_string *self)
-{
- self->length = 0;
- self->fail = GL_FALSE;
-}
-
-static GLboolean
-grow (slang_string *self, GLuint size)
-{
- if (self->fail)
- return GL_FALSE;
- if (size > self->capacity) {
- /* do not overflow 32-bit range */
- assert (size < 0x80000000);
-
- self->data = (char *) (_mesa_realloc (self->data, self->capacity, size * 2));
- self->capacity = size * 2;
- if (self->data == NULL) {
- self->capacity = 0;
- self->fail = GL_TRUE;
- return GL_FALSE;
- }
- }
- return GL_TRUE;
-}
-
-GLvoid
-slang_string_push (slang_string *self, const slang_string *str)
-{
- if (str->fail) {
- self->fail = GL_TRUE;
- return;
- }
- if (grow (self, self->length + str->length)) {
- memcpy (&self->data[self->length], str->data, str->length);
- self->length += str->length;
- }
-}
-
-GLvoid
-slang_string_pushc (slang_string *self, const char c)
-{
- if (grow (self, self->length + 1)) {
- self->data[self->length] = c;
- self->length++;
- }
-}
-
-GLvoid
-slang_string_pushs (slang_string *self, const char *cstr, GLuint len)
-{
- if (grow (self, self->length + len)) {
- memcpy (&self->data[self->length], cstr, len);
- self->length += len;
- }
-}
-
-GLvoid
-slang_string_pushi (slang_string *self, GLint i)
-{
- char buffer[12];
-
- _mesa_snprintf (buffer, sizeof(buffer), "%d", i);
- slang_string_pushs (self, buffer, strlen (buffer));
-}
-
-const char *
-slang_string_cstr (slang_string *self)
-{
- if (grow (self, self->length + 1))
- self->data[self->length] = '\0';
- return self->data;
-}
-
-/* slang_atom_pool */
-
-void
-slang_atom_pool_construct(slang_atom_pool * pool)
-{
- GLuint i;
-
- for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
- pool->entries[i] = NULL;
-}
-
-void
-slang_atom_pool_destruct (slang_atom_pool * pool)
-{
- GLuint i;
-
- for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) {
- slang_atom_entry * entry;
-
- entry = pool->entries[i];
- while (entry != NULL) {
- slang_atom_entry *next = entry->next;
- _slang_free(entry->id);
- _slang_free(entry);
- entry = next;
- }
- }
-}
-
-/*
- * Search the atom pool for an atom with a given name.
- * If atom is not found, create and add it to the pool.
- * Returns ATOM_NULL if the atom was not found and the function failed
- * to create a new atom.
- */
-slang_atom
-slang_atom_pool_atom(slang_atom_pool * pool, const char * id)
-{
- GLuint hash;
- const char * p = id;
- slang_atom_entry ** entry;
-
- /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */
- hash = 0;
- while (*p != '\0') {
- GLuint g;
-
- hash = (hash << 4) + (GLuint) (*p++);
- g = hash & 0xf0000000;
- if (g != 0)
- hash ^= g >> 24;
- hash &= ~g;
- }
- hash %= SLANG_ATOM_POOL_SIZE;
-
- /* Now the hash points to a linked list of atoms with names that
- * have the same hash value. Search the linked list for a given
- * name.
- */
- entry = &pool->entries[hash];
- while (*entry != NULL) {
- /* If the same, return the associated atom. */
- if (slang_string_compare((**entry).id, id) == 0)
- return (slang_atom) (**entry).id;
- /* Grab the next atom in the linked list. */
- entry = &(**entry).next;
- }
-
- /* Okay, we have not found an atom. Create a new entry for it.
- * Note that the <entry> points to the last entry's <next> field.
- */
- *entry = (slang_atom_entry *) _slang_alloc(sizeof(slang_atom_entry));
- if (*entry == NULL)
- return SLANG_ATOM_NULL;
-
- /* Initialize a new entry. Because we'll need the actual name of
- * the atom, we use the pointer to this string as an actual atom's
- * value.
- */
- (**entry).next = NULL;
- (**entry).id = _slang_strdup(id);
- if ((**entry).id == NULL)
- return SLANG_ATOM_NULL;
- return (slang_atom) (**entry).id;
-}
-
-/**
- * Return the name of a given atom.
- */
-const char *
-slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom)
-{
- return (const char *) (atom);
-}
diff --git a/src/mesa/slang/slang_utility.h b/src/mesa/slang/slang_utility.h
deleted file mode 100644
index cb9b6d2aaaa..00000000000
--- a/src/mesa/slang/slang_utility.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.3
- *
- * Copyright (C) 2005-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 SLANG_UTILITY_H
-#define SLANG_UTILITY_H
-
-
-#include "main/glheader.h"
-
-/* Compile-time assertions. If the expression is zero, try to declare an
- * array of size [-1] to cause compilation error.
- */
-#define static_assert(expr) do { int _array[(expr) ? 1 : -1]; (void) _array[0]; } while (0)
-
-
-#define slang_string_compare(str1, str2) strcmp (str1, str2)
-#define slang_string_copy(dst, src) strcpy (dst, src)
-#define slang_string_length(str) strlen (str)
-
-char *slang_string_concat (char *, const char *);
-
-/* slang_string */
-
-typedef struct
-{
- char *data;
- GLuint length;
- GLuint capacity;
- GLboolean fail;
-} slang_string;
-
-GLvoid
-slang_string_init (slang_string *);
-
-GLvoid
-slang_string_free (slang_string *);
-
-GLvoid
-slang_string_reset (slang_string *);
-
-GLvoid
-slang_string_push (slang_string *, const slang_string *);
-
-GLvoid
-slang_string_pushc (slang_string *, const char);
-
-GLvoid
-slang_string_pushs (slang_string *, const char *, GLuint);
-
-GLvoid
-slang_string_pushi (slang_string *, GLint);
-
-const char *
-slang_string_cstr (slang_string *);
-
-/* slang_atom */
-
-typedef GLvoid *slang_atom;
-
-#define SLANG_ATOM_NULL ((slang_atom) 0)
-
-typedef struct slang_atom_entry_
-{
- char *id;
- struct slang_atom_entry_ *next;
-} slang_atom_entry;
-
-#define SLANG_ATOM_POOL_SIZE 1023
-
-typedef struct slang_atom_pool_
-{
- slang_atom_entry *entries[SLANG_ATOM_POOL_SIZE];
-} slang_atom_pool;
-
-GLvoid slang_atom_pool_construct (slang_atom_pool *);
-GLvoid slang_atom_pool_destruct (slang_atom_pool *);
-slang_atom slang_atom_pool_atom (slang_atom_pool *, const char *);
-const char *slang_atom_pool_id (slang_atom_pool *, slang_atom);
-
-
-#endif
diff --git a/src/mesa/slang/slang_vartable.c b/src/mesa/slang/slang_vartable.c
deleted file mode 100644
index 83716315788..00000000000
--- a/src/mesa/slang/slang_vartable.c
+++ /dev/null
@@ -1,362 +0,0 @@
-
-#include "main/imports.h"
-#include "program/program.h"
-#include "program/prog_print.h"
-#include "slang_compile.h"
-#include "slang_compile_variable.h"
-#include "slang_emit.h"
-#include "slang_mem.h"
-#include "slang_vartable.h"
-#include "slang_ir.h"
-
-
-static int dbg = 0;
-
-
-typedef enum {
- FREE,
- VAR,
- TEMP
-} TempState;
-
-
-/**
- * Variable/register info for one variable scope.
- */
-struct table
-{
- int Level;
- int NumVars;
- slang_variable **Vars; /* array [NumVars] */
-
- TempState Temps[MAX_PROGRAM_TEMPS * 4]; /* per-component state */
- int ValSize[MAX_PROGRAM_TEMPS * 4]; /**< For debug only */
-
- struct table *Parent; /** Parent scope table */
-};
-
-
-/**
- * A variable table is a stack of tables, one per scope.
- */
-struct slang_var_table_
-{
- GLint CurLevel;
- GLuint MaxRegisters;
- struct table *Top; /**< Table at top of stack */
-};
-
-
-
-slang_var_table *
-_slang_new_var_table(GLuint maxRegisters)
-{
- slang_var_table *vt
- = (slang_var_table *) _slang_alloc(sizeof(slang_var_table));
- if (vt) {
- vt->MaxRegisters = maxRegisters;
- }
- return vt;
-}
-
-
-void
-_slang_delete_var_table(slang_var_table *vt)
-{
- if (vt->Top) {
- _mesa_problem(NULL, "non-empty var table in _slang_delete_var_table()");
- return;
- }
- _slang_free(vt);
-}
-
-
-
-/**
- * Create new table on top of vartable stack.
- * Used when we enter a {} block.
- */
-void
-_slang_push_var_table(slang_var_table *vt)
-{
- struct table *t = (struct table *) _slang_alloc(sizeof(struct table));
- if (t) {
- t->Level = vt->CurLevel++;
- t->Parent = vt->Top;
- if (t->Parent) {
- /* copy the info indicating which temp regs are in use */
- memcpy(t->Temps, t->Parent->Temps, sizeof(t->Temps));
- memcpy(t->ValSize, t->Parent->ValSize, sizeof(t->ValSize));
- }
- vt->Top = t;
- if (dbg) printf("Pushing level %d\n", t->Level);
- }
-}
-
-
-/**
- * Pop top entry from variable table.
- * Used when we leave a {} block.
- */
-void
-_slang_pop_var_table(slang_var_table *vt)
-{
- struct table *t = vt->Top;
- int i;
-
- if (dbg) printf("Popping level %d\n", t->Level);
-
- /* free the storage allocated for each variable */
- for (i = 0; i < t->NumVars; i++) {
- slang_ir_storage *store = t->Vars[i]->store;
- GLint j;
- GLuint comp;
- if (dbg) printf(" Free var %s, size %d at %d.%s\n",
- (char*) t->Vars[i]->a_name, store->Size,
- store->Index,
- _mesa_swizzle_string(store->Swizzle, 0, 0));
-
- if (store->File == PROGRAM_SAMPLER) {
- /* samplers have no storage */
- continue;
- }
-
- if (store->Size == 1)
- comp = GET_SWZ(store->Swizzle, 0);
- else
- comp = 0;
-
- /* store->Index may be -1 if we run out of registers */
- if (store->Index >= 0) {
- for (j = 0; j < store->Size; j++) {
- assert(t->Temps[store->Index * 4 + j + comp] == VAR);
- t->Temps[store->Index * 4 + j + comp] = FREE;
- }
- }
- store->Index = -1;
- }
- if (t->Parent) {
- /* just verify that any remaining allocations in this scope
- * were for temps
- */
- for (i = 0; i < (int) vt->MaxRegisters * 4; i++) {
- if (t->Temps[i] != FREE && t->Parent->Temps[i] == FREE) {
- if (dbg) printf(" Free reg %d\n", i/4);
- assert(t->Temps[i] == TEMP);
- }
- }
- }
-
- if (t->Vars) {
- _slang_free(t->Vars);
- t->Vars = NULL;
- }
-
- vt->Top = t->Parent;
- _slang_free(t);
- vt->CurLevel--;
-}
-
-
-/**
- * Add a new variable to the given var/symbol table.
- */
-void
-_slang_add_variable(slang_var_table *vt, slang_variable *v)
-{
- struct table *t;
- assert(vt);
- t = vt->Top;
- assert(t);
- if (dbg) printf("Adding var %s, store %p\n", (char *) v->a_name, (void *) v->store);
- t->Vars = (slang_variable **)
- _slang_realloc(t->Vars,
- t->NumVars * sizeof(slang_variable *),
- (t->NumVars + 1) * sizeof(slang_variable *));
- t->Vars[t->NumVars] = v;
- t->NumVars++;
-}
-
-
-/**
- * Look for variable by name in given table.
- * If not found, Parent table will be searched.
- */
-slang_variable *
-_slang_find_variable(const slang_var_table *vt, slang_atom name)
-{
- struct table *t = vt->Top;
- while (1) {
- int i;
- for (i = 0; i < t->NumVars; i++) {
- if (t->Vars[i]->a_name == name)
- return t->Vars[i];
- }
- if (t->Parent)
- t = t->Parent;
- else
- return NULL;
- }
-}
-
-
-/**
- * Allocation helper.
- * \param size var size in floats
- * \return position for var, measured in floats
- */
-static GLint
-alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp)
-{
- struct table *t = vt->Top;
- /* if size == 1, allocate anywhere, else, pos must be multiple of 4 */
- const GLuint step = (size == 1) ? 1 : 4;
- GLuint i, j;
- assert(size > 0); /* number of floats */
-
- for (i = 0; i <= vt->MaxRegisters * 4 - size; i += step) {
- GLuint found = 0;
- for (j = 0; j < (GLuint) size; j++) {
- assert(i + j < 4 * MAX_PROGRAM_TEMPS);
- if (i + j < vt->MaxRegisters * 4 && t->Temps[i + j] == FREE) {
- found++;
- }
- else {
- break;
- }
- }
- if (found == size) {
- /* found block of size free regs */
- if (size > 1)
- assert(i % 4 == 0);
- for (j = 0; j < (GLuint) size; j++) {
- assert(i + j < 4 * MAX_PROGRAM_TEMPS);
- t->Temps[i + j] = isTemp ? TEMP : VAR;
- }
- assert(i < MAX_PROGRAM_TEMPS * 4);
- t->ValSize[i] = size;
- return i;
- }
- }
-
- /* if we get here, we ran out of registers */
- return -1;
-}
-
-
-/**
- * Allocate temp register(s) for storing a variable.
- * \param size size needed, in floats
- * \param swizzle returns swizzle mask for accessing var in register
- * \return register allocated, or -1
- */
-GLboolean
-_slang_alloc_var(slang_var_table *vt, slang_ir_storage *store)
-{
- struct table *t = vt->Top;
- int i;
-
- if (store->File == PROGRAM_SAMPLER) {
- /* don't really allocate storage */
- store->Index = 0;
- return GL_TRUE;
- }
-
- i = alloc_reg(vt, store->Size, GL_FALSE);
- if (i < 0)
- return GL_FALSE;
-
- store->Index = i / 4;
- store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
-
- if (dbg)
- printf("Alloc var storage sz %d at %d.%s (level %d) store %p\n",
- store->Size, store->Index,
- _mesa_swizzle_string(store->Swizzle, 0, 0),
- t->Level,
- (void*) store);
-
- return GL_TRUE;
-}
-
-
-
-/**
- * Allocate temp register(s) for storing an unnamed intermediate value.
- */
-GLboolean
-_slang_alloc_temp(slang_var_table *vt, slang_ir_storage *store)
-{
- struct table *t = vt->Top;
- const int i = alloc_reg(vt, store->Size, GL_TRUE);
- if (i < 0)
- return GL_FALSE;
-
- assert(store->Index < 0);
-
- store->Index = i / 4;
- store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
-
- if (dbg) printf("Alloc temp sz %d at %d.%s (level %d) store %p\n",
- store->Size, store->Index,
- _mesa_swizzle_string(store->Swizzle, 0, 0), t->Level,
- (void *) store);
-
- return GL_TRUE;
-}
-
-
-void
-_slang_free_temp(slang_var_table *vt, slang_ir_storage *store)
-{
- struct table *t = vt->Top;
- GLuint i;
- GLint r = store->Index;
- assert(store->Size > 0);
- assert(r >= 0);
- assert((GLuint)r + store->Size <= vt->MaxRegisters * 4);
- if (dbg) printf("Free temp sz %d at %d.%s (level %d) store %p\n",
- store->Size, r,
- _mesa_swizzle_string(store->Swizzle, 0, 0),
- t->Level, (void *) store);
- if (store->Size == 1) {
- const GLuint comp = GET_SWZ(store->Swizzle, 0);
- /* we can actually fail some of these assertions because of the
- * troublesome IR_SWIZZLE handling.
- */
-#if 0
- assert(store->Swizzle == MAKE_SWIZZLE4(comp, comp, comp, comp));
- assert(comp < 4);
- assert(t->ValSize[r * 4 + comp] == 1);
-#endif
- assert(t->Temps[r * 4 + comp] == TEMP);
- t->Temps[r * 4 + comp] = FREE;
- }
- else {
- /*assert(store->Swizzle == SWIZZLE_NOOP);*/
- assert(t->ValSize[r*4] == store->Size);
- for (i = 0; i < (GLuint) store->Size; i++) {
- assert(t->Temps[r * 4 + i] == TEMP);
- t->Temps[r * 4 + i] = FREE;
- }
- }
-}
-
-
-GLboolean
-_slang_is_temp(const slang_var_table *vt, const slang_ir_storage *store)
-{
- struct table *t = vt->Top;
- GLuint comp;
- assert(store->Index >= 0);
- assert(store->Index < (int) vt->MaxRegisters);
- if (store->Swizzle == SWIZZLE_NOOP)
- comp = 0;
- else
- comp = GET_SWZ(store->Swizzle, 0);
-
- if (t->Temps[store->Index * 4 + comp] == TEMP)
- return GL_TRUE;
- else
- return GL_FALSE;
-}
diff --git a/src/mesa/slang/slang_vartable.h b/src/mesa/slang/slang_vartable.h
deleted file mode 100644
index 97945b89d03..00000000000
--- a/src/mesa/slang/slang_vartable.h
+++ /dev/null
@@ -1,45 +0,0 @@
-
-#ifndef SLANG_VARTABLE_H
-#define SLANG_VARTABLE_H
-
-#include "main/glheader.h"
-#include "slang_utility.h"
-
-struct slang_ir_storage_;
-
-typedef struct slang_var_table_ slang_var_table;
-
-struct slang_variable_;
-
-extern slang_var_table *
-_slang_new_var_table(GLuint maxRegisters);
-
-extern void
-_slang_delete_var_table(slang_var_table *vt);
-
-extern void
-_slang_push_var_table(slang_var_table *parent);
-
-extern void
-_slang_pop_var_table(slang_var_table *t);
-
-extern void
-_slang_add_variable(slang_var_table *t, struct slang_variable_ *v);
-
-extern struct slang_variable_ *
-_slang_find_variable(const slang_var_table *t, slang_atom name);
-
-extern GLboolean
-_slang_alloc_var(slang_var_table *t, struct slang_ir_storage_ *store);
-
-extern GLboolean
-_slang_alloc_temp(slang_var_table *t, struct slang_ir_storage_ *store);
-
-extern void
-_slang_free_temp(slang_var_table *t, struct slang_ir_storage_ *store);
-
-extern GLboolean
-_slang_is_temp(const slang_var_table *t, const struct slang_ir_storage_ *store);
-
-
-#endif /* SLANG_VARTABLE_H */
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index f01b60c4fc8..9156024d471 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -250,26 +250,8 @@ PROGRAM_SOURCES = \
program/programopt.c \
program/symbol_table.c
-SLANG_SOURCES = \
- slang/slang_builtin.c \
- slang/slang_codegen.c \
- slang/slang_compile.c \
- slang/slang_compile_function.c \
- slang/slang_compile_operation.c \
- slang/slang_compile_struct.c \
- slang/slang_compile_variable.c \
- slang/slang_emit.c \
- slang/slang_ir.c \
- slang/slang_label.c \
- slang/slang_link.c \
- slang/slang_log.c \
- slang/slang_mem.c \
- slang/slang_print.c \
- slang/slang_simplify.c \
- slang/slang_storage.c \
- slang/slang_typeinfo.c \
- slang/slang_vartable.c \
- slang/slang_utility.c
+SHADER_CXX_SOURCES = \
+ program/ir_to_mesa.cpp
ASM_C_SOURCES = \
x86/common_x86.c \
@@ -324,8 +306,10 @@ MESA_SOURCES = \
$(SWRAST_SOURCES) \
$(SWRAST_SETUP_SOURCES) \
$(COMMON_DRIVER_SOURCES)\
- $(ASM_C_SOURCES) \
- $(SLANG_SOURCES)
+ $(ASM_C_SOURCES)
+
+MESA_CXX_SOURCES = \
+ $(SHADER_CXX_SOURCES)
# Sources for building Gallium drivers
MESA_GALLIUM_SOURCES = \
@@ -335,12 +319,15 @@ MESA_GALLIUM_SOURCES = \
$(STATETRACKER_SOURCES) \
$(PROGRAM_SOURCES) \
ppc/common_ppc.c \
- x86/common_x86.c \
- $(SLANG_SOURCES)
+ x86/common_x86.c
+
+MESA_GALLIUM_CXX_SOURCES = \
+ $(SHADER_CXX_SOURCES)
# All the core C sources, for dependency checking
ALL_SOURCES = \
$(MESA_SOURCES) \
+ $(MESA_CXX_SOURCES) \
$(MESA_ASM_SOURCES) \
$(STATETRACKER_SOURCES)
@@ -349,10 +336,12 @@ ALL_SOURCES = \
MESA_OBJECTS = \
$(MESA_SOURCES:.c=.o) \
+ $(MESA_CXX_SOURCES:.cpp=.o) \
$(MESA_ASM_SOURCES:.S=.o)
MESA_GALLIUM_OBJECTS = \
$(MESA_GALLIUM_SOURCES:.c=.o) \
+ $(MESA_GALLIUM_CXX_SOURCES:.cpp=.o) \
$(MESA_ASM_SOURCES:.S=.o)
@@ -362,8 +351,7 @@ COMMON_DRIVER_OBJECTS = $(COMMON_DRIVER_SOURCES:.c=.o)
### Other archives/libraries
GLSL_LIBS = \
- $(TOP)/src/glsl/pp/libglslpp.a \
- $(TOP)/src/glsl/cl/libglslcl.a
+ $(TOP)/src/glsl/libglsl.a
### Include directories
diff --git a/src/mesa/state_tracker/st_cb_accum.h b/src/mesa/state_tracker/st_cb_accum.h
index 7d52481c82e..06425dc8a35 100644
--- a/src/mesa/state_tracker/st_cb_accum.h
+++ b/src/mesa/state_tracker/st_cb_accum.h
@@ -41,6 +41,8 @@ extern void st_init_accum_functions(struct dd_function_table *functions);
#else
+#include "main/compiler.h"
+
static INLINE void
st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
{
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 0b8ecd27cb9..8da5cbb5e68 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -275,7 +275,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
/**
* Create texture to hold bitmap pattern.
*/
- pt = st_texture_create(st, PIPE_TEXTURE_2D, st->bitmap.tex_format,
+ pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format,
0, width, height, 1,
PIPE_BIND_SAMPLER_VIEW);
if (!pt) {
@@ -304,7 +304,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
}
static GLuint
-setup_bitmap_vertex_data(struct st_context *st,
+setup_bitmap_vertex_data(struct st_context *st, bool normalized,
int x, int y, int width, int height,
float z, const float color[4])
{
@@ -316,12 +316,20 @@ setup_bitmap_vertex_data(struct st_context *st,
const GLfloat x1 = (GLfloat)(x + width);
const GLfloat y0 = (GLfloat)y;
const GLfloat y1 = (GLfloat)(y + height);
- const GLfloat sLeft = (GLfloat)0.0, sRight = (GLfloat)1.0;
- const GLfloat tTop = (GLfloat)0.0, tBot = (GLfloat)1.0 - tTop;
+ GLfloat sLeft = (GLfloat)0.0, sRight = (GLfloat)1.0;
+ GLfloat tTop = (GLfloat)0.0, tBot = (GLfloat)1.0 - tTop;
const GLfloat clip_x0 = (GLfloat)(x0 / fb_width * 2.0 - 1.0);
const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0);
const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0);
const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0);
+ const GLuint max_slots = 1; /* 4096 / sizeof(st->bitmap.vertices); */
+ GLuint i;
+
+ if(!normalized)
+ {
+ sRight = width;
+ tBot = height;
+ }
/* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
* no_flush) updates to buffers where we know there is no conflict
@@ -333,9 +341,6 @@ setup_bitmap_vertex_data(struct st_context *st,
* price of allocating a new buffer for each bitmap cache-flush to
* avoid synchronous rendering.
*/
- const GLuint max_slots = 1; /* 4096 / sizeof(st->bitmap.vertices); */
- GLuint i;
-
if (st->bitmap.vbuf_slot >= max_slots) {
pipe_resource_reference(&st->bitmap.vbuf, NULL);
st->bitmap.vbuf_slot = 0;
@@ -462,7 +467,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
for (i = 0; i < st->state.num_samplers; i++) {
samplers[i] = &st->state.samplers[i];
}
- samplers[stfp->bitmap_sampler] = &st->bitmap.sampler;
+ samplers[stfp->bitmap_sampler] = &st->bitmap.samplers[sv->texture->target != PIPE_TEXTURE_RECT];
cso_set_samplers(cso, num, (const struct pipe_sampler_state **) samplers);
}
@@ -499,7 +504,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
z = z * 2.0 - 1.0;
/* draw textured quad */
- offset = setup_bitmap_vertex_data(st, x, y, width, height, z, color);
+ offset = setup_bitmap_vertex_data(st, sv->texture->target != PIPE_TEXTURE_RECT, x, y, width, height, z, color);
util_draw_vertex_buffer(pipe, st->bitmap.vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
@@ -761,7 +766,7 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
if (pt) {
struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt);
- assert(pt->target == PIPE_TEXTURE_2D);
+ assert(pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT);
if (sv) {
draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2],
@@ -789,7 +794,7 @@ st_init_bitmap_functions(struct dd_function_table *functions)
void
st_init_bitmap(struct st_context *st)
{
- struct pipe_sampler_state *sampler = &st->bitmap.sampler;
+ struct pipe_sampler_state *sampler = &st->bitmap.samplers[0];
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
@@ -801,7 +806,8 @@ st_init_bitmap(struct st_context *st)
sampler->min_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
sampler->mag_img_filter = PIPE_TEX_FILTER_NEAREST;
- sampler->normalized_coords = 1;
+ st->bitmap.samplers[1] = *sampler;
+ st->bitmap.samplers[1].normalized_coords = 1;
/* init baseline rasterizer state once */
memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index 1f73f503f6f..536748402f4 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -40,6 +40,7 @@
#include "st_cb_fbo.h"
#include "util/u_blit.h"
+#include "util/u_inlines.h"
void
@@ -152,38 +153,33 @@ st_BlitFramebuffer(GLcontext *ctx,
/* depth and/or stencil blit */
/* get src/dst depth surfaces */
- struct st_renderbuffer *srcDepthRb =
+ struct gl_renderbuffer_attachment *srcDepth =
+ &readFB->Attachment[BUFFER_DEPTH];
+ struct gl_renderbuffer_attachment *dstDepth =
+ &drawFB->Attachment[BUFFER_DEPTH];
+ struct gl_renderbuffer_attachment *srcStencil =
+ &readFB->Attachment[BUFFER_STENCIL];
+ struct gl_renderbuffer_attachment *dstStencil =
+ &drawFB->Attachment[BUFFER_STENCIL];
+
+ struct st_renderbuffer *srcDepthRb =
st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
struct st_renderbuffer *dstDepthRb =
st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
- struct pipe_surface *srcDepthSurf =
- srcDepthRb ? srcDepthRb->surface : NULL;
struct pipe_surface *dstDepthSurf =
dstDepthRb ? dstDepthRb->surface : NULL;
- /* get src/dst stencil surfaces */
- struct st_renderbuffer *srcStencilRb =
- st_renderbuffer(readFB->Attachment[BUFFER_STENCIL].Renderbuffer);
- struct st_renderbuffer *dstStencilRb =
- st_renderbuffer(drawFB->Attachment[BUFFER_STENCIL].Renderbuffer);
- struct pipe_surface *srcStencilSurf =
- srcStencilRb ? srcStencilRb->surface : NULL;
- struct pipe_surface *dstStencilSurf =
- dstStencilRb ? dstStencilRb->surface : NULL;
-
if ((mask & depthStencil) == depthStencil &&
- srcDepthSurf == srcStencilSurf &&
- dstDepthSurf == dstStencilSurf) {
- struct pipe_subresource srcSub;
-
- srcSub.face = srcDepthRb->surface->face;
- srcSub.level = srcDepthRb->surface->level;
+ st_is_depth_stencil_combined(srcDepth, srcStencil) &&
+ st_is_depth_stencil_combined(dstDepth, dstStencil)) {
/* Blitting depth and stencil values between combined
* depth/stencil buffers. This is the ideal case for such buffers.
*/
- util_blit_pixels(st->blit,
- srcDepthRb->texture, srcSub, srcX0, srcY0, srcX1, srcY1,
+ util_blit_pixels(st->blit, srcDepthRb->texture,
+ u_subresource(srcDepthRb->surface->face,
+ srcDepthRb->surface->level),
+ srcX0, srcY0, srcX1, srcY1,
srcDepthRb->surface->zslice,
dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
@@ -192,8 +188,13 @@ st_BlitFramebuffer(GLcontext *ctx,
/* blitting depth and stencil separately */
if (mask & GL_DEPTH_BUFFER_BIT) {
- /* blit Z only */
- _mesa_problem(ctx, "st_BlitFramebuffer(DEPTH) not completed");
+ util_blit_pixels(st->blit, srcDepthRb->texture,
+ u_subresource(srcDepthRb->surface->face,
+ srcDepthRb->surface->level),
+ srcX0, srcY0, srcX1, srcY1,
+ srcDepthRb->surface->zslice,
+ dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
+ 0.0, pFilter);
}
if (mask & GL_STENCIL_BUFFER_BIT) {
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 69a3dd45e80..1147b1950e2 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -301,37 +301,10 @@ static struct pipe_resource *
alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
enum pipe_format texFormat)
{
- struct pipe_context *pipe = st->pipe;
- struct pipe_screen *screen = pipe->screen;
struct pipe_resource *pt;
- int ptw, pth;
-
- ptw = width;
- pth = height;
-
- /* Need to use POT texture? */
- if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
- int l2pt, maxSize;
-
- l2pt = util_logbase2(width);
- if (1 << l2pt != width) {
- ptw = 1 << (l2pt + 1);
- }
-
- l2pt = util_logbase2(height);
- if (1 << l2pt != height) {
- pth = 1 << (l2pt + 1);
- }
-
- /* Check against maximum texture size */
- maxSize = 1 << (pipe->screen->get_param(pipe->screen,
- PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
- assert(ptw <= maxSize);
- assert(pth <= maxSize);
- }
- pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
- ptw, pth, 1, PIPE_BIND_SAMPLER_VIEW);
+ pt = st_texture_create(st, st->internal_target, texFormat, 0,
+ width, height, 1, PIPE_BIND_SAMPLER_VIEW);
return pt;
}
@@ -536,6 +509,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
struct cso_context *cso = st->cso_context;
GLfloat x0, y0, x1, y1;
GLsizei maxSize;
+ boolean normalized = sv->texture->target != PIPE_TEXTURE_RECT;
/* limit checks */
/* XXX if DrawPixels image is larger than max texture size, break
@@ -579,7 +553,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
- sampler.normalized_coords = 1;
+ sampler.normalized_coords = normalized;
cso_single_sampler(cso, 0, &sampler);
if (st->pixel_xfer.pixelmap_enabled) {
@@ -635,8 +609,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
z = z * 2.0 - 1.0;
draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
- (GLfloat) width / sv->texture->width0,
- (GLfloat) height / sv->texture->height0);
+ normalized ? ((GLfloat) width / sv->texture->width0) : (GLfloat)width,
+ normalized ? ((GLfloat) height / sv->texture->height0) : (GLfloat)height);
/* restore state */
cso_restore_rasterizer(cso);
@@ -1002,7 +976,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
srcFormat = rbRead->texture->format;
- if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE_2D, sample_count,
+ if (screen->is_format_supported(screen, srcFormat, st->internal_target, sample_count,
PIPE_BIND_SAMPLER_VIEW, 0)) {
texFormat = srcFormat;
}
@@ -1010,13 +984,13 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
/* srcFormat can't be used as a texture format */
if (type == GL_DEPTH) {
texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
- PIPE_TEXTURE_2D, sample_count,
+ st->internal_target, sample_count,
PIPE_BIND_DEPTH_STENCIL);
assert(texFormat != PIPE_FORMAT_NONE);
}
else {
/* default color format */
- texFormat = st_choose_format(screen, GL_RGBA, PIPE_TEXTURE_2D,
+ texFormat = st_choose_format(screen, GL_RGBA, st->internal_target,
sample_count, PIPE_BIND_SAMPLER_VIEW);
assert(texFormat != PIPE_FORMAT_NONE);
}
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c
index 037e576fabe..3145416383b 100644
--- a/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/src/mesa/state_tracker/st_cb_eglimage.c
@@ -128,7 +128,8 @@ st_bind_surface(GLcontext *ctx, GLenum target,
_mesa_set_fetch_functions(texImage, 2);
/* FIXME create a non-default sampler view from the pipe_surface? */
- pipe_resource_reference(&stImage->pt, ps->texture);
+ pipe_resource_reference(&stObj->pt, ps->texture);
+ pipe_resource_reference(&stImage->pt, stObj->pt);
stObj->width0 = ps->width;
stObj->height0 = ps->height;
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 13119ce2037..71bd4729e03 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -108,7 +108,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
/* Setup new texture template.
*/
memset(&template, 0, sizeof(template));
- template.target = PIPE_TEXTURE_2D;
+ template.target = st->internal_target;
template.format = format;
template.width0 = width;
template.height0 = height;
@@ -448,6 +448,30 @@ st_validate_attachment(struct pipe_screen *screen,
/**
+ * Check if two renderbuffer attachments name a combined depth/stencil
+ * renderbuffer.
+ */
+GLboolean
+st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth,
+ const struct gl_renderbuffer_attachment *stencil)
+{
+ assert(depth && stencil);
+
+ if (depth->Type == stencil->Type) {
+ if (depth->Type == GL_RENDERBUFFER_EXT &&
+ depth->Renderbuffer == stencil->Renderbuffer)
+ return GL_TRUE;
+
+ if (depth->Type == GL_TEXTURE &&
+ depth->Texture == stencil->Texture)
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+
+/**
* Check that the framebuffer configuration is valid in terms of what
* the driver can support.
*
@@ -543,6 +567,7 @@ st_ReadBuffer(GLcontext *ctx, GLenum buffer)
void st_init_fbo_functions(struct dd_function_table *functions)
{
+#if FEATURE_EXT_framebuffer_object
functions->NewFramebuffer = st_new_framebuffer;
functions->NewRenderbuffer = st_new_renderbuffer;
functions->BindFramebuffer = st_bind_framebuffer;
@@ -550,6 +575,7 @@ void st_init_fbo_functions(struct dd_function_table *functions)
functions->RenderTexture = st_render_texture;
functions->FinishRenderTexture = st_finish_render_texture;
functions->ValidateFramebuffer = st_validate_framebuffer;
+#endif
/* no longer needed by core Mesa, drivers handle resizes...
functions->ResizeBuffers = st_resize_buffers;
*/
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index 62a9bbcb25f..3e9815c1b13 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -88,4 +88,9 @@ st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb,
struct pipe_context *pipe);
+extern GLboolean
+st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth,
+ const struct gl_renderbuffer_attachment *stencil);
+
+
#endif /* ST_CB_FBO_H */
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index b8493dab93f..6ab03ec9391 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -68,16 +68,20 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
ubyte *stmap;
GLint j;
+ if (strb->Base.Wrapped) {
+ strb = st_renderbuffer(strb->Base.Wrapped);
+ }
+
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
y = ctx->DrawBuffer->Height - y - height;
}
/* Create a read transfer from the renderbuffer's texture */
- pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture,
- 0, 0, 0,
- PIPE_TRANSFER_READ, x, y,
- width, height);
+ pt = pipe_get_transfer(pipe, strb->texture,
+ 0, 0, 0, /* face, level, zslice */
+ PIPE_TRANSFER_READ,
+ x, y, width, height);
/* map the stencil buffer */
stmap = pipe_transfer_map(pipe, pt);
@@ -230,10 +234,10 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb,
y = strb->texture->height0 - y - height;
}
- trans = pipe_get_transfer(st_context(ctx)->pipe, strb->texture,
- 0, 0, 0,
- PIPE_TRANSFER_READ, x, y,
- width, height);
+ trans = pipe_get_transfer(pipe, strb->texture,
+ 0, 0, 0, /* face, level, zslice */
+ PIPE_TRANSFER_READ,
+ x, y, width, height);
if (!trans) {
return GL_FALSE;
}
@@ -359,6 +363,9 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
else if (format == GL_DEPTH_COMPONENT) {
strb = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
+ if (strb->Base.Wrapped) {
+ strb = st_renderbuffer(strb->Base.Wrapped);
+ }
}
else {
/* Read color buffer */
@@ -394,10 +401,10 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
/* Create a read transfer from the renderbuffer's texture */
- trans = pipe_get_transfer(st_context(ctx)->pipe, strb->texture,
- 0, 0, 0,
- PIPE_TRANSFER_READ, x, y,
- width, height);
+ trans = pipe_get_transfer(pipe, strb->texture,
+ 0, 0, 0, /* face, level, zslice */
+ PIPE_TRANSFER_READ,
+ x, y, width, height);
/* determine bottom-to-top vs. top-to-bottom order */
if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 4c3e3688dd8..9eb14033eeb 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -74,9 +74,11 @@ gl_target_to_pipe(GLenum target)
return PIPE_TEXTURE_1D;
case GL_TEXTURE_2D:
- case GL_TEXTURE_RECTANGLE_NV:
return PIPE_TEXTURE_2D;
+ case GL_TEXTURE_RECTANGLE_NV:
+ return PIPE_TEXTURE_RECT;
+
case GL_TEXTURE_3D:
return PIPE_TEXTURE_3D;
@@ -449,7 +451,7 @@ compress_with_blit(GLcontext * ctx,
/* Create the temporary source texture
*/
memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
+ templ.target = st->internal_target;
templ.format = st_mesa_format_to_pipe_format(mesa_format);
templ.width0 = width;
templ.height0 = height;
@@ -546,6 +548,14 @@ st_TexImage(GLcontext * ctx,
/* switch to "normal" */
if (stObj->surface_based) {
_mesa_clear_texture_object(ctx, texObj);
+ pipe_resource_reference(&stObj->pt, NULL);
+
+ /* oops, need to init this image again */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ width, height, depth, border, internalFormat);
+ _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+ internalFormat, format, type);
+
stObj->surface_based = GL_FALSE;
}
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 2ce5f087536..3b046962efe 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -125,6 +125,11 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
st_init_generate_mipmap(st);
st_init_blit(st);
+ if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
+ st->internal_target = PIPE_TEXTURE_2D;
+ else
+ st->internal_target = PIPE_TEXTURE_RECT;
+
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
st->state.sampler_list[i] = &st->state.samplers[i];
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 60c25fb8f00..991feee3001 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -149,7 +149,7 @@ struct st_context
/** for glBitmap */
struct {
struct pipe_rasterizer_state rasterizer;
- struct pipe_sampler_state sampler;
+ struct pipe_sampler_state samplers[2];
enum pipe_format tex_format;
void *vs;
float vertices[4][3][4]; /**< vertex pos + color + texcoord */
@@ -182,6 +182,7 @@ struct st_context
void *passthrough_fs; /**< simple pass-through frag shader */
+ enum pipe_texture_target internal_target;
struct gen_mipmap_state *gen_mipmap;
struct blit_state *blit;
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 5b054892702..318e08886c7 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -691,9 +691,6 @@ st_draw_vbo(GLcontext *ctx,
pipe->set_vertex_buffers(pipe, num_vbuffers, vbuffer);
cso_set_vertex_elements(st->cso_context, num_velements, velements);
- if (num_vbuffers == 0 || num_velements == 0)
- return;
-
setup_index_buffer(ctx, ib, &ibuffer);
pipe->set_index_buffer(pipe, &ibuffer);
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 5cf26663341..df05c7f70df 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -104,14 +104,15 @@ st_feedback_draw_vbo(GLcontext *ctx,
struct draw_context *draw = st->draw;
const struct st_vertex_program *vp;
const struct pipe_shader_state *vs;
- struct pipe_resource *index_buffer_handle = 0;
struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS];
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
+ struct pipe_index_buffer ibuffer;
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
struct pipe_transfer *ib_transfer = NULL;
struct pipe_transfer *cb_transfer;
GLuint attr, i;
ubyte *mapped_constants;
+ const void *mapped_indices = NULL;
assert(draw);
@@ -204,17 +205,19 @@ st_feedback_draw_vbo(GLcontext *ctx,
draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers);
draw_set_vertex_elements(draw, vp->num_inputs, velements);
+ memset(&ibuffer, 0, sizeof(ibuffer));
if (ib) {
struct gl_buffer_object *bufobj = ib->obj;
- unsigned indexSize;
- void *map;
switch (ib->type) {
case GL_UNSIGNED_INT:
- indexSize = 4;
+ ibuffer.index_size = 4;
break;
case GL_UNSIGNED_SHORT:
- indexSize = 2;
+ ibuffer.index_size = 2;
+ break;
+ case GL_UNSIGNED_BYTE:
+ ibuffer.index_size = 1;
break;
default:
assert(0);
@@ -224,23 +227,20 @@ st_feedback_draw_vbo(GLcontext *ctx,
if (bufobj && bufobj->Name) {
struct st_buffer_object *stobj = st_buffer_object(bufobj);
- index_buffer_handle = stobj->buffer;
-
- map = pipe_buffer_map(pipe, index_buffer_handle,
- PIPE_TRANSFER_READ, &ib_transfer);
+ pipe_resource_reference(&ibuffer.buffer, stobj->buffer);
+ ibuffer.offset = pointer_to_offset(ib->ptr);
- draw_set_mapped_element_buffer(draw, indexSize, 0, map);
+ mapped_indices = pipe_buffer_map(pipe, stobj->buffer,
+ PIPE_TRANSFER_READ, &ib_transfer);
}
else {
- draw_set_mapped_element_buffer(draw, indexSize, 0, (void *) ib->ptr);
- ib_transfer = NULL;
+ /* skip setting ibuffer.buffer as the draw module does not use it */
+ mapped_indices = ib->ptr;
}
- }
- else {
- /* no index/element buffer */
- draw_set_mapped_element_buffer(draw, 0, 0, NULL);
- }
+ draw_set_index_buffer(draw, &ibuffer);
+ draw_set_mapped_index_buffer(draw, mapped_indices);
+ }
/* map constant buffers */
mapped_constants = pipe_buffer_map(pipe,
@@ -273,9 +273,14 @@ st_feedback_draw_vbo(GLcontext *ctx,
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}
- if (index_buffer_handle) {
- pipe_buffer_unmap(pipe, index_buffer_handle, ib_transfer);
- draw_set_mapped_element_buffer(draw, 0, 0, NULL);
+
+ if (ib) {
+ draw_set_mapped_index_buffer(draw, NULL);
+ draw_set_index_buffer(draw, NULL);
+
+ if (ib_transfer)
+ pipe_buffer_unmap(pipe, ibuffer.buffer, ib_transfer);
+ pipe_resource_reference(&ibuffer.buffer, NULL);
}
}
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 90e78679e47..6cd74db897b 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -161,6 +161,13 @@ void st_init_limits(struct st_context *st)
pc->MaxNativeTemps = screen->get_param(screen, PIPE_CAP_MAX_VS_TEMPS);
pc->MaxNativeAddressRegs = screen->get_param(screen, PIPE_CAP_MAX_VS_ADDRS);
pc->MaxNativeParameters = screen->get_param(screen, PIPE_CAP_MAX_VS_CONSTS);
+
+ /* PIPE_CAP_MAX_FS_INPUTS specifies the number of COLORn + GENERICn inputs
+ * and is set in MaxNativeAttribs. It's always 2 colors + N generic
+ * attributes. The GLSL compiler never uses COLORn for varyings, so we
+ * subtract the 2 colors to get the maximum number of varyings (generic
+ * attributes) supported by a driver. */
+ c->MaxVarying = screen->get_param(screen, PIPE_CAP_MAX_FS_INPUTS) - 2;
}
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index c9fa7a62e19..1ed79524b2c 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -35,7 +35,6 @@
#include "main/imports.h"
#include "main/context.h"
#include "main/texstore.h"
-#include "main/enums.h"
#include "main/image.h"
#include "main/macros.h"
@@ -78,7 +77,9 @@ st_format_datatype(enum pipe_format format)
return GL_UNSIGNED_SHORT;
}
else if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
- format == PIPE_FORMAT_S8_USCALED_Z24_UNORM) {
+ format == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
+ format == PIPE_FORMAT_Z24X8_UNORM ||
+ format == PIPE_FORMAT_X8Z24_UNORM) {
return GL_UNSIGNED_INT_24_8;
}
else {
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 2afc682e0b1..ccce574c364 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -42,6 +42,7 @@
#include "main/texstate.h"
#include "main/texfetch.h"
#include "main/framebuffer.h"
+#include "main/fbobject.h"
#include "main/renderbuffer.h"
#include "st_texture.h"
@@ -247,6 +248,9 @@ st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb,
int samples;
boolean sw;
+ if (!stfb->iface)
+ return FALSE;
+
/* do not distinguish depth/stencil buffers */
if (idx == BUFFER_STENCIL)
idx = BUFFER_DEPTH;
@@ -299,6 +303,10 @@ st_visual_to_context_mode(const struct st_visual *visual,
{
memset(mode, 0, sizeof(*mode));
+ /* FBO-only context */
+ if (!visual)
+ return;
+
if (st_visual_have_buffers(visual, ST_ATTACHMENT_BACK_LEFT_MASK))
mode->doubleBufferMode = GL_TRUE;
if (st_visual_have_buffers(visual,
@@ -422,6 +430,15 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi)
if (!stfb)
return NULL;
+ /* for FBO-only context */
+ if (!stfbi) {
+ GLframebuffer *base = _mesa_get_incomplete_framebuffer();
+
+ stfb->Base = *base;
+
+ return stfb;
+ }
+
st_visual_to_context_mode(stfbi->visual, &mode);
_mesa_initialize_window_framebuffer(&stfb->Base, &mode);
@@ -693,10 +710,14 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
st_framebuffer_validate(stread, st);
/* modify the draw/read buffers of the context */
- st_visual_to_default_buffer(stdraw->iface->visual,
- &st->ctx->Color.DrawBuffer[0], NULL);
- st_visual_to_default_buffer(stread->iface->visual,
- &st->ctx->Pixel.ReadBuffer, NULL);
+ if (stdraw->iface) {
+ st_visual_to_default_buffer(stdraw->iface->visual,
+ &st->ctx->Color.DrawBuffer[0], NULL);
+ }
+ if (stread->iface) {
+ st_visual_to_default_buffer(stread->iface->visual,
+ &st->ctx->Pixel.ReadBuffer, NULL);
+ }
ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base);
}
@@ -748,6 +769,8 @@ st_manager_flush_frontbuffer(struct st_context *st)
if (!strb)
return;
+ /* never a dummy fb */
+ assert(stfb->iface);
stfb->iface->flush_front(stfb->iface, ST_ATTACHMENT_FRONT_LEFT);
}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index a19dcc92534..0ed822b8c27 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -32,9 +32,10 @@
*/
#include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/p_state.h"
-#include "pipe/p_context.h"
#include "tgsi/tgsi_ureg.h"
#include "st_mesa_to_tgsi.h"
#include "st_context.h"
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 91528c227b2..8c2d8b6154b 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -207,6 +207,9 @@ st_translate_vertex_program(struct st_context *st,
enum pipe_error error;
unsigned num_outputs;
+ _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT);
+ _mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_VARYING);
+
ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
if (ureg == NULL) {
FREE(vpv);
@@ -298,6 +301,8 @@ st_translate_fragment_program(struct st_context *st,
ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
uint fs_num_outputs = 0;
+ _mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
+
/*
* Convert Mesa program inputs to TGSI input register semantics.
*/
@@ -485,6 +490,9 @@ st_translate_geometry_program(struct st_context *st,
GLuint maxSlot = 0;
struct ureg_program *ureg;
+ _mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_OUTPUT);
+ _mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_VARYING);
+
ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY );
if (ureg == NULL) {
return;
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index add6e949dfb..c6cf2ba061b 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -64,7 +64,7 @@ st_texture_create(struct st_context *st,
struct pipe_resource pt, *newtex;
struct pipe_screen *screen = st->pipe->screen;
- assert(target <= PIPE_TEXTURE_CUBE);
+ assert(target < PIPE_MAX_TEXTURE_TYPES);
assert(width0 > 0);
assert(height0 > 0);
assert(depth0 > 0);
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index d8d8a80b7d7..f76a2b68ecd 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -950,7 +950,7 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
v->attrib[FRAG_ATTRIB_COL1][2],
v->attrib[FRAG_ATTRIB_COL1][3]);
_mesa_debug(ctx, "fog %f\n", v->attrib[FRAG_ATTRIB_FOGC][0]);
- _mesa_debug(ctx, "index %d\n", v->attrib[FRAG_ATTRIB_CI][0]);
+ _mesa_debug(ctx, "index %f\n", v->attrib[FRAG_ATTRIB_CI][0]);
_mesa_debug(ctx, "pointsize %f\n", v->pointSize);
_mesa_debug(ctx, "\n");
}
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index c32a5044438..1759e578870 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -785,7 +785,7 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
start, end, count, type, indices,
ctx->Array.ArrayObj->_MaxElement - 1,
ctx->Array.ElementArrayBufferObj->Name,
- ctx->Array.ElementArrayBufferObj->Size);
+ (int) ctx->Array.ElementArrayBufferObj->Size);
}
if (0)
@@ -811,7 +811,7 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
start, end, count, type, indices, max,
ctx->Array.ArrayObj->_MaxElement - 1,
ctx->Array.ElementArrayBufferObj->Name,
- ctx->Array.ElementArrayBufferObj->Size);
+ (int) ctx->Array.ElementArrayBufferObj->Size);
}
}
/* XXX we could also find the min index and compare to 'start'
diff --git a/src/mesa/x86/3dnow.h b/src/mesa/x86/3dnow.h
index df9f2638d76..1c1fedcd4f3 100644
--- a/src/mesa/x86/3dnow.h
+++ b/src/mesa/x86/3dnow.h
@@ -31,8 +31,6 @@
#ifndef __3DNOW_H__
#define __3DNOW_H__
-#include "math/m_xform.h"
-
void _mesa_init_3dnow_transform_asm( void );
#endif
diff --git a/src/mesa/x86/common_x86.c b/src/mesa/x86/common_x86.c
index 5efdb4f24a6..f763a3aa8a4 100644
--- a/src/mesa/x86/common_x86.c
+++ b/src/mesa/x86/common_x86.c
@@ -55,7 +55,7 @@
/** Bitmask of X86_FEATURE_x bits */
int _mesa_x86_cpu_features = 0x0;
-
+static int detection_debug = GL_FALSE;
/* No reason for this to be public.
*/
@@ -190,7 +190,8 @@ void _mesa_check_os_sse_support( void )
#else
/* Do nothing on other platforms for now.
*/
- _mesa_debug(NULL, "Not testing OS support for SSE, leaving enabled.\n");
+ if (detection_debug)
+ _mesa_debug(NULL, "Not testing OS support for SSE, leaving enabled.\n");
#endif /* __FreeBSD__ */
}
@@ -232,7 +233,8 @@ _mesa_get_x86_features(void)
_mesa_x86_cpuid(0, &result, (GLuint *)(cpu_vendor + 0), (GLuint *)(cpu_vendor + 8), (GLuint *)(cpu_vendor + 4));
cpu_vendor[12] = '\0';
- _mesa_debug(NULL, "CPU vendor: %s\n", cpu_vendor);
+ if (detection_debug)
+ _mesa_debug(NULL, "CPU vendor: %s\n", cpu_vendor);
/* get cpu features */
cpu_features = _mesa_x86_cpuid_edx(1);
@@ -284,10 +286,49 @@ _mesa_get_x86_features(void)
_mesa_x86_cpuid(0x80000002+ofs, (GLuint *)(cpu_name + (16*ofs)+0), (GLuint *)(cpu_name + (16*ofs)+4), (GLuint *)(cpu_name + (16*ofs)+8), (GLuint *)(cpu_name + (16*ofs)+12));
cpu_name[48] = '\0'; /* the name should be NULL terminated, but just to be sure */
- _mesa_debug(NULL, "CPU name: %s\n", cpu_name);
+ if (detection_debug)
+ _mesa_debug(NULL, "CPU name: %s\n", cpu_name);
}
}
}
+
+#ifdef USE_MMX_ASM
+ if ( cpu_has_mmx ) {
+ if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) {
+ if (detection_debug)
+ _mesa_debug(NULL, "MMX cpu detected.\n");
+ } else {
+ _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX);
+ }
+ }
+#endif
+
+#ifdef USE_3DNOW_ASM
+ if ( cpu_has_3dnow ) {
+ if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) {
+ if (detection_debug)
+ _mesa_debug(NULL, "3DNow! cpu detected.\n");
+ } else {
+ _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW);
+ }
+ }
+#endif
+
+#ifdef USE_SSE_ASM
+ if ( cpu_has_xmm ) {
+ if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) {
+ if (detection_debug)
+ _mesa_debug(NULL, "SSE cpu detected.\n");
+ if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) {
+ _mesa_check_os_sse_support();
+ }
+ } else {
+ _mesa_debug(NULL, "SSE cpu detected, but switched off by user.\n");
+ _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
+ }
+ }
+#endif
+
#endif /* USE_X86_ASM */
}
diff --git a/src/mesa/x86/mmx.h b/src/mesa/x86/mmx.h
index 5641936bdb0..47a0d4b54dd 100644
--- a/src/mesa/x86/mmx.h
+++ b/src/mesa/x86/mmx.h
@@ -26,6 +26,9 @@
#ifndef ASM_MMX_H
#define ASM_MMX_H
+#include "main/compiler.h"
+#include "main/mtypes.h"
+
extern void _ASMAPI
_mesa_mmx_blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLvoid *rgba, const GLvoid *dest,
diff --git a/src/mesa/x86/sse.h b/src/mesa/x86/sse.h
index 521f91e4117..e92ddc13941 100644
--- a/src/mesa/x86/sse.h
+++ b/src/mesa/x86/sse.h
@@ -31,8 +31,6 @@
#ifndef __SSE_H__
#define __SSE_H__
-#include "math/m_xform.h"
-
void _mesa_init_sse_transform_asm( void );
#endif
diff --git a/src/mesa/x86/x86_xform.c b/src/mesa/x86/x86_xform.c
index c834e2b468b..3dcc55e16b6 100644
--- a/src/mesa/x86/x86_xform.c
+++ b/src/mesa/x86/x86_xform.c
@@ -114,42 +114,13 @@ void _mesa_init_all_x86_transform_asm( void )
_mesa_init_x86_transform_asm();
}
-#ifdef USE_MMX_ASM
- if ( cpu_has_mmx ) {
- if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) {
- _mesa_debug(NULL, "MMX cpu detected.\n");
- } else {
- _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX);
- }
+ if (cpu_has_3dnow) {
+ _mesa_init_3dnow_transform_asm();
}
-#endif
-
-#ifdef USE_3DNOW_ASM
- if ( cpu_has_3dnow ) {
- if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) {
- _mesa_debug(NULL, "3DNow! cpu detected.\n");
- _mesa_init_3dnow_transform_asm();
- } else {
- _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW);
- }
- }
-#endif
-#ifdef USE_SSE_ASM
if ( cpu_has_xmm ) {
- if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) {
- _mesa_debug(NULL, "SSE cpu detected.\n");
- if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) {
- _mesa_check_os_sse_support();
- }
- if ( cpu_has_xmm ) {
- _mesa_init_sse_transform_asm();
- }
- } else {
- _mesa_debug(NULL, "SSE cpu detected, but switched off by user.\n");
- _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
- }
+ _mesa_init_sse_transform_asm();
}
-#endif
+
#endif
}