aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r--mesalib/src/mesa/Makefile376
-rw-r--r--mesalib/src/mesa/SConscript784
-rw-r--r--mesalib/src/mesa/main/arrayobj.c1156
-rw-r--r--mesalib/src/mesa/main/shaderapi.c8
-rw-r--r--mesalib/src/mesa/main/shaderobj.c826
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp42
-rw-r--r--mesalib/src/mesa/program/register_allocate.c913
-rw-r--r--mesalib/src/mesa/program/sampler.cpp278
8 files changed, 2188 insertions, 2195 deletions
diff --git a/mesalib/src/mesa/Makefile b/mesalib/src/mesa/Makefile
index c9a5eaf5b..a6025e990 100644
--- a/mesalib/src/mesa/Makefile
+++ b/mesalib/src/mesa/Makefile
@@ -1,188 +1,188 @@
-# src/mesa/Makefile
-
-TOP = ../..
-include $(TOP)/configs/current
-
-MESA_LIBS := libmesa.a libmesagallium.a
-DEPENDS := depend
-
-MESA_OBJ_DIR := .
-
-
-include sources.mak
-
-# adjust object dirs
-MESA_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_OBJECTS))
-MESA_GALLIUM_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_GALLIUM_OBJECTS))
-
-# define preprocessor flags
-MESA_CPPFLAGS := $(API_DEFINES) $(DEFINES)
-
-# append include dirs
-MESA_CPPFLAGS += $(INCLUDE_DIRS) $(TALLOC_CFLAGS)
-
-# tidy compiler flags
-CFLAGS := $(filter-out $(DEFINES), $(CFLAGS))
-CXXFLAGS := $(filter-out $(DEFINES), $(CXXFLAGS))
-
-# LLVM is needed for the state tracker
-MESA_CFLAGS := $(LLVM_CFLAGS)
-
-define mesa-cc-c
- @mkdir -p $(dir $@)
- $(CC) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_CFLAGS) $(CFLAGS)
-endef
-
-define mesa-cxx-c
- @mkdir -p $(dir $@)
- $(CXX) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_CFLAGS) $(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)
-
-# Default: build dependencies, then asm_subdirs, GLSL built-in lib,
-# then convenience libs (.a) and finally the device drivers:
-default: $(DEPENDS) asm_subdirs $(MESA_LIBS) driver_subdirs
-
-main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py
- $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES1.1 > $@
-
-main/api_exec_es2.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py
- $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES2.0 > $@
-
-######################################################################
-# Helper libraries used by many drivers:
-
-# Make archive of core mesa object files
-libmesa.a: $(MESA_OBJECTS) $(GLSL_LIBS)
- @ $(MKLIB) -o mesa -static $(MESA_OBJECTS) $(GLSL_LIBS)
-
-# Make archive of subset of core mesa object files for gallium
-libmesagallium.a: $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS)
- @ $(MKLIB) -o mesagallium -static $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS)
-
-######################################################################
-# Device drivers
-driver_subdirs: $(MESA_LIBS)
- @ (cd drivers && $(MAKE))
-
-
-######################################################################
-# Assembly subdirs
-asm_subdirs:
- @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \
- (cd x86 && $(MAKE)) || exit 1 ; \
- fi
- @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \
- (cd x86 && $(MAKE)) || exit 1 ; \
- (cd x86-64 && $(MAKE)) || exit 1 ; \
- fi
-
-
-######################################################################
-# Dependency generation
-
-depend: $(ALL_SOURCES)
- @ echo "running $(MKDEP)"
- @ touch depend
- @$(MKDEP) $(MKDEP_OPTIONS) -p$(MESA_OBJ_DIR)/ $(MESA_CPPFLAGS) \
- $(ALL_SOURCES) > /dev/null 2>/dev/null
-
-######################################################################
-# Installation rules
-
-# this isn't fleshed out yet but is probably the way to go in the future
-new_install:
- (cd drivers && $(MAKE) install)
-
-
-# XXX replace this with new_install above someday
-install: default
- @for driver in $(DRIVER_DIRS) ; do \
- case "$$driver" in \
- osmesa) if [ "$(DRIVER_DIRS)" = osmesa ]; then \
- $(MAKE) install-headers install-osmesa || exit 1 ; \
- else \
- $(MAKE) install-osmesa || exit 1 ; \
- fi ;; \
- dri) $(MAKE) install-libgl install-dri || exit 1 ;; \
- *) $(MAKE) install-libgl || exit 1 ;; \
- esac ; \
- done
-
-pcedit = \
- -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
- -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \
- -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \
- -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' \
-
-
-gl_pcedit = sed \
- $(pcedit) \
- -e 's,@GL_PC_REQ_PRIV@,$(GL_PC_REQ_PRIV),' \
- -e 's,@GL_PC_LIB_PRIV@,$(GL_PC_LIB_PRIV),' \
- -e 's,@GL_PC_CFLAGS@,$(GL_PC_CFLAGS),' \
- -e 's,@GLX_TLS@,$(GLX_TLS),' \
- -e 's,@GL_LIB@,$(GL_LIB),'
-
-gl.pc: gl.pc.in
- $(gl_pcedit) $< > $@
-
-osmesa_pcedit = sed \
- $(pcedit) \
- -e 's,@OSMESA_LIB@,$(OSMESA_LIB),' \
- -e 's,@OSMESA_PC_REQ@,$(OSMESA_PC_REQ),' \
- -e 's,@OSMESA_PC_LIB_PRIV@,$(OSMESA_PC_LIB_PRIV),'
-
-osmesa.pc: osmesa.pc.in
- $(osmesa_pcedit) $< > $@
-
-install-headers:
- $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/GL
- $(INSTALL) -m 644 $(TOP)/include/GL/*.h \
- $(DESTDIR)$(INSTALL_INC_DIR)/GL
-
-install-libgl: default gl.pc install-headers
- $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
- $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
- $(MINSTALL) $(TOP)/$(LIB_DIR)/$(GL_LIB_GLOB) \
- $(DESTDIR)$(INSTALL_LIB_DIR)
- $(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
-
-install-osmesa: default osmesa.pc
- $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
- $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
- $(MINSTALL) $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_GLOB) \
- $(DESTDIR)$(INSTALL_LIB_DIR)
- $(INSTALL) -m 644 osmesa.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
-
-install-dri: default
- cd drivers/dri && $(MAKE) install
-
-
-
-# Emacs tags
-tags:
- etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
-
-clean:
- -rm -f */*.o
- -rm -f */*/*.o
- -rm -f depend depend.bak libmesa.a libmesagallium.a
- -rm -f drivers/*/*.o
- -rm -f *.pc
- -@cd drivers/dri && $(MAKE) clean
- -@cd drivers/x11 && $(MAKE) clean
- -@cd drivers/osmesa && $(MAKE) clean
- -@cd x86 && $(MAKE) clean
- -@cd x86-64 && $(MAKE) clean
-
-
--include $(DEPENDS)
+# src/mesa/Makefile
+
+TOP = ../..
+include $(TOP)/configs/current
+
+MESA_LIBS := libmesa.a libmesagallium.a
+DEPENDS := depend
+
+MESA_OBJ_DIR := .
+
+
+include sources.mak
+
+# adjust object dirs
+MESA_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_OBJECTS))
+MESA_GALLIUM_OBJECTS := $(addprefix $(MESA_OBJ_DIR)/, $(MESA_GALLIUM_OBJECTS))
+
+# define preprocessor flags
+MESA_CPPFLAGS := $(API_DEFINES) $(DEFINES)
+
+# append include dirs
+MESA_CPPFLAGS += $(INCLUDE_DIRS)
+
+# tidy compiler flags
+CFLAGS := $(filter-out $(DEFINES), $(CFLAGS))
+CXXFLAGS := $(filter-out $(DEFINES), $(CXXFLAGS))
+
+# LLVM is needed for the state tracker
+MESA_CFLAGS := $(LLVM_CFLAGS)
+
+define mesa-cc-c
+ @mkdir -p $(dir $@)
+ $(CC) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_CFLAGS) $(CFLAGS)
+endef
+
+define mesa-cxx-c
+ @mkdir -p $(dir $@)
+ $(CXX) -c -o $@ $< $($(1)_CPPFLAGS) $($(1)_CFLAGS) $(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)
+
+# Default: build dependencies, then asm_subdirs, GLSL built-in lib,
+# then convenience libs (.a) and finally the device drivers:
+default: $(DEPENDS) asm_subdirs $(MESA_LIBS) driver_subdirs
+
+main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py
+ $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES1.1 > $@
+
+main/api_exec_es2.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py
+ $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES2.0 > $@
+
+######################################################################
+# Helper libraries used by many drivers:
+
+# Make archive of core mesa object files
+libmesa.a: $(MESA_OBJECTS) $(GLSL_LIBS)
+ @ $(MKLIB) -o mesa -static $(MESA_OBJECTS) $(GLSL_LIBS)
+
+# Make archive of subset of core mesa object files for gallium
+libmesagallium.a: $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS)
+ @ $(MKLIB) -o mesagallium -static $(MESA_GALLIUM_OBJECTS) $(GLSL_LIBS)
+
+######################################################################
+# Device drivers
+driver_subdirs: $(MESA_LIBS)
+ @ (cd drivers && $(MAKE))
+
+
+######################################################################
+# Assembly subdirs
+asm_subdirs:
+ @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_ASM ; then \
+ (cd x86 && $(MAKE)) || exit 1 ; \
+ fi
+ @ if echo "$(ASM_FLAGS)" | grep -q USE_X86_64_ASM ; then \
+ (cd x86 && $(MAKE)) || exit 1 ; \
+ (cd x86-64 && $(MAKE)) || exit 1 ; \
+ fi
+
+
+######################################################################
+# Dependency generation
+
+depend: $(ALL_SOURCES)
+ @ echo "running $(MKDEP)"
+ @ touch depend
+ @$(MKDEP) $(MKDEP_OPTIONS) -p$(MESA_OBJ_DIR)/ $(MESA_CPPFLAGS) \
+ $(ALL_SOURCES) > /dev/null 2>/dev/null
+
+######################################################################
+# Installation rules
+
+# this isn't fleshed out yet but is probably the way to go in the future
+new_install:
+ (cd drivers && $(MAKE) install)
+
+
+# XXX replace this with new_install above someday
+install: default
+ @for driver in $(DRIVER_DIRS) ; do \
+ case "$$driver" in \
+ osmesa) if [ "$(DRIVER_DIRS)" = osmesa ]; then \
+ $(MAKE) install-headers install-osmesa || exit 1 ; \
+ else \
+ $(MAKE) install-osmesa || exit 1 ; \
+ fi ;; \
+ dri) $(MAKE) install-libgl install-dri || exit 1 ;; \
+ *) $(MAKE) install-libgl || exit 1 ;; \
+ esac ; \
+ done
+
+pcedit = \
+ -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
+ -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \
+ -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \
+ -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' \
+
+
+gl_pcedit = sed \
+ $(pcedit) \
+ -e 's,@GL_PC_REQ_PRIV@,$(GL_PC_REQ_PRIV),' \
+ -e 's,@GL_PC_LIB_PRIV@,$(GL_PC_LIB_PRIV),' \
+ -e 's,@GL_PC_CFLAGS@,$(GL_PC_CFLAGS),' \
+ -e 's,@GLX_TLS@,$(GLX_TLS),' \
+ -e 's,@GL_LIB@,$(GL_LIB),'
+
+gl.pc: gl.pc.in
+ $(gl_pcedit) $< > $@
+
+osmesa_pcedit = sed \
+ $(pcedit) \
+ -e 's,@OSMESA_LIB@,$(OSMESA_LIB),' \
+ -e 's,@OSMESA_PC_REQ@,$(OSMESA_PC_REQ),' \
+ -e 's,@OSMESA_PC_LIB_PRIV@,$(OSMESA_PC_LIB_PRIV),'
+
+osmesa.pc: osmesa.pc.in
+ $(osmesa_pcedit) $< > $@
+
+install-headers:
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/GL
+ $(INSTALL) -m 644 $(TOP)/include/GL/*.h \
+ $(DESTDIR)$(INSTALL_INC_DIR)/GL
+
+install-libgl: default gl.pc install-headers
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/$(GL_LIB_GLOB) \
+ $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
+
+install-osmesa: default osmesa.pc
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_GLOB) \
+ $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(INSTALL) -m 644 osmesa.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
+
+install-dri: default
+ cd drivers/dri && $(MAKE) install
+
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
+
+clean:
+ -rm -f */*.o
+ -rm -f */*/*.o
+ -rm -f depend depend.bak libmesa.a libmesagallium.a
+ -rm -f drivers/*/*.o
+ -rm -f *.pc
+ -@cd drivers/dri && $(MAKE) clean
+ -@cd drivers/x11 && $(MAKE) clean
+ -@cd drivers/osmesa && $(MAKE) clean
+ -@cd x86 && $(MAKE) clean
+ -@cd x86-64 && $(MAKE) clean
+
+
+-include $(DEPENDS)
diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript
index 6ac8b0d4c..ea04fb1a0 100644
--- a/mesalib/src/mesa/SConscript
+++ b/mesalib/src/mesa/SConscript
@@ -1,393 +1,391 @@
-#######################################################################
-# SConscript for Mesa
-
-
-Import('*')
-
-env = env.Clone()
-
-env.Append(CPPPATH = [
- '#/src/mapi',
- '#/src/glsl',
- '#/src/mesa',
-])
-
-env.Append(CPPDEFINES = [
- 'FEATURE_GL=1',
-])
-
-if env['platform'] == 'windows':
- env.Append(CPPDEFINES = [
- '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers
- 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers
- ])
- if not env['gles']:
- # prevent _glapi_* from being declared __declspec(dllimport)
- env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS'])
-
- env.Prepend(CPPPATH = ['#src/talloc'])
-else:
- env.Append(CPPDEFINES = [
- 'IN_DRI_DRIVER', # enable the remap table (for DRI drivers)
- ])
-
-#
-# Source files
-#
-
-main_sources = [
- 'main/api_arrayelt.c',
- 'main/api_exec.c',
- 'main/api_loopback.c',
- 'main/api_noop.c',
- 'main/api_validate.c',
- 'main/accum.c',
- 'main/arbprogram.c',
- 'main/atifragshader.c',
- 'main/attrib.c',
- 'main/arrayobj.c',
- 'main/blend.c',
- 'main/bufferobj.c',
- 'main/buffers.c',
- 'main/clear.c',
- 'main/clip.c',
- 'main/colortab.c',
- 'main/condrender.c',
- 'main/context.c',
- 'main/convolve.c',
- 'main/cpuinfo.c',
- 'main/debug.c',
- 'main/depth.c',
- 'main/depthstencil.c',
- 'main/dlist.c',
- 'main/dlopen.c',
- 'main/drawpix.c',
- 'main/drawtex.c',
- 'main/enable.c',
- 'main/enums.c',
- 'main/eval.c',
- 'main/execmem.c',
- 'main/extensions.c',
- 'main/fbobject.c',
- 'main/feedback.c',
- 'main/ffvertex_prog.c',
- 'main/fog.c',
- 'main/formats.c',
- 'main/framebuffer.c',
- 'main/get.c',
- 'main/getstring.c',
- 'main/hash.c',
- 'main/hint.c',
- 'main/histogram.c',
- 'main/image.c',
- 'main/imports.c',
- 'main/light.c',
- 'main/lines.c',
- 'main/matrix.c',
- 'main/mipmap.c',
- 'main/mm.c',
- 'main/multisample.c',
- 'main/nvprogram.c',
- 'main/pack.c',
- 'main/pixel.c',
- 'main/pixelstore.c',
- 'main/pixeltransfer.c',
- 'main/points.c',
- 'main/polygon.c',
- 'main/querymatrix.c',
- 'main/queryobj.c',
- 'main/rastpos.c',
- 'main/readpix.c',
- 'main/remap.c',
- 'main/renderbuffer.c',
- 'main/scissor.c',
- 'main/shaderapi.c',
- 'main/shaderobj.c',
- 'main/shared.c',
- 'main/state.c',
- 'main/stencil.c',
- 'main/syncobj.c',
- 'main/texcompress.c',
- 'main/texcompress_s3tc.c',
- 'main/texcompress_fxt1.c',
- 'main/texenv.c',
- 'main/texenvprogram.c',
- 'main/texfetch.c',
- 'main/texformat.c',
- 'main/texgen.c',
- 'main/texgetimage.c',
- 'main/teximage.c',
- 'main/texobj.c',
- 'main/texpal.c',
- 'main/texparam.c',
- 'main/texrender.c',
- 'main/texstate.c',
- 'main/texstore.c',
- 'main/transformfeedback.c',
- 'main/uniforms.c',
- 'main/varray.c',
- 'main/version.c',
- 'main/viewport.c',
- 'main/vtxfmt.c',
-]
-
-math_sources = [
- 'math/m_debug_clip.c',
- 'math/m_debug_norm.c',
- 'math/m_debug_xform.c',
- 'math/m_eval.c',
- 'math/m_matrix.c',
- 'math/m_translate.c',
- 'math/m_vector.c',
- 'math/m_xform.c',
-]
-
-vbo_sources = [
- 'vbo/vbo_context.c',
- 'vbo/vbo_exec.c',
- 'vbo/vbo_exec_api.c',
- 'vbo/vbo_exec_array.c',
- 'vbo/vbo_exec_draw.c',
- 'vbo/vbo_exec_eval.c',
- 'vbo/vbo_rebase.c',
- 'vbo/vbo_split.c',
- 'vbo/vbo_split_copy.c',
- 'vbo/vbo_split_inplace.c',
- 'vbo/vbo_save.c',
- 'vbo/vbo_save_api.c',
- 'vbo/vbo_save_draw.c',
- 'vbo/vbo_save_loopback.c',
-]
-
-vf_sources = [
- 'vf/vf.c',
- 'vf/vf_generic.c',
- 'vf/vf_sse.c',
-]
-
-statetracker_sources = [
- 'state_tracker/st_atom.c',
- 'state_tracker/st_atom_blend.c',
- 'state_tracker/st_atom_clip.c',
- 'state_tracker/st_atom_constbuf.c',
- 'state_tracker/st_atom_depth.c',
- 'state_tracker/st_atom_framebuffer.c',
- 'state_tracker/st_atom_msaa.c',
- 'state_tracker/st_atom_pixeltransfer.c',
- 'state_tracker/st_atom_sampler.c',
- 'state_tracker/st_atom_scissor.c',
- 'state_tracker/st_atom_shader.c',
- 'state_tracker/st_atom_rasterizer.c',
- 'state_tracker/st_atom_stipple.c',
- 'state_tracker/st_atom_texture.c',
- 'state_tracker/st_atom_viewport.c',
- 'state_tracker/st_cb_accum.c',
- 'state_tracker/st_cb_bitmap.c',
- 'state_tracker/st_cb_blit.c',
- 'state_tracker/st_cb_bufferobjects.c',
- 'state_tracker/st_cb_clear.c',
- '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',
- 'state_tracker/st_cb_program.c',
- 'state_tracker/st_cb_queryobj.c',
- 'state_tracker/st_cb_rasterpos.c',
- 'state_tracker/st_cb_readpixels.c',
- 'state_tracker/st_cb_strings.c',
- 'state_tracker/st_cb_texture.c',
- 'state_tracker/st_cb_viewport.c',
- 'state_tracker/st_cb_xformfb.c',
- 'state_tracker/st_context.c',
- 'state_tracker/st_debug.c',
- 'state_tracker/st_draw.c',
- 'state_tracker/st_draw_feedback.c',
- 'state_tracker/st_extensions.c',
- 'state_tracker/st_format.c',
- 'state_tracker/st_gen_mipmap.c',
- 'state_tracker/st_manager.c',
- 'state_tracker/st_mesa_to_tgsi.c',
- 'state_tracker/st_program.c',
- 'state_tracker/st_texture.c',
-]
-
-program_sources = [
- 'program/arbprogparse.c',
- 'program/hash_table.c',
- 'program/ir_to_mesa.cpp',
- 'program/lex.yy.c',
- 'program/nvfragparse.c',
- 'program/nvvertparse.c',
- 'program/program.c',
- 'program/program_parse.tab.c',
- 'program/program_parse_extra.c',
- 'program/prog_cache.c',
- 'program/prog_execute.c',
- 'program/prog_instruction.c',
- 'program/prog_noise.c',
- 'program/prog_optimize.c',
- 'program/prog_parameter.c',
- 'program/prog_parameter_layout.c',
- 'program/prog_print.c',
- 'program/prog_statevars.c',
- 'program/prog_uniform.c',
- 'program/programopt.c',
- 'program/sampler.cpp',
- 'program/symbol_table.c',
-]
-
-mesa_sources = (
- main_sources +
- math_sources +
- program_sources +
- vbo_sources +
- vf_sources +
- statetracker_sources
-)
-
-if env['gles']:
- from sys import executable as python_cmd
-
- env.Append(CPPDEFINES = ['FEATURE_ES1=1', 'FEATURE_ES2=1'])
-
- # generate GLES sources
- gles_sources = []
- gles_sources += env.CodeGenerate(
- target = 'main/api_exec_es1.c',
- script = 'main/es_generator.py',
- source = 'main/APIspec.xml',
- command = python_cmd + ' $SCRIPT -S $SOURCE -V GLES1.1 > $TARGET'
- )
- gles_sources += env.CodeGenerate(
- target = 'main/api_exec_es2.c',
- script = 'main/es_generator.py',
- source = 'main/APIspec.xml',
- command = python_cmd + ' $SCRIPT -S $SOURCE -V GLES2.0 > $TARGET'
- )
-
- # generate GLES headers
- GLAPI = '#src/mapi/glapi/'
- gles_headers = []
- gles_headers += env.CodeGenerate(
- target = 'es1api/main/glapidispatch.h',
- script = GLAPI + 'gen/gl_table.py',
- source = GLAPI + 'gen-es/es1_API.xml',
- command = python_cmd + ' $SCRIPT -c -m remap_table -f $SOURCE > $TARGET',
- )
- gles_headers += env.CodeGenerate(
- target = 'es1api/main/remap_helper.h',
- script = GLAPI + 'gen/remap_helper.py',
- source = GLAPI + 'gen-es/es1_API.xml',
- command = python_cmd + ' $SCRIPT -f $SOURCE > $TARGET',
- )
- gles_headers += env.CodeGenerate(
- target = 'es2api/main/glapidispatch.h',
- script = GLAPI + 'gen/gl_table.py',
- source = GLAPI + 'gen-es/es2_API.xml',
- command = python_cmd + ' $SCRIPT -c -m remap_table -f $SOURCE > $TARGET',
- )
- gles_headers += env.CodeGenerate(
- target = 'es2api/main/remap_helper.h',
- script = GLAPI + 'gen/remap_helper.py',
- source = GLAPI + 'gen-es/es2_API.xml',
- command = python_cmd + ' $SCRIPT -f $SOURCE > $TARGET',
- )
-
- env.Depends(gles_sources, gles_headers)
-
- # gles_sources #include gles_headers with full path
- env.Append(CPPPATH = [gles_headers[0].dir.up().up()])
-
- mesa_sources += gles_sources
-
-#
-# Assembly sources
-#
-if env['gcc'] and env['platform'] != 'windows':
- if env['machine'] == 'x86':
- env.Append(CPPDEFINES = [
- 'USE_X86_ASM',
- 'USE_MMX_ASM',
- 'USE_3DNOW_ASM',
- 'USE_SSE_ASM',
- ])
- mesa_sources += [
- 'x86/common_x86.c',
- 'x86/x86_xform.c',
- 'x86/3dnow.c',
- 'x86/sse.c',
- 'x86/common_x86_asm.S',
- 'x86/x86_xform2.S',
- 'x86/x86_xform3.S',
- 'x86/x86_xform4.S',
- 'x86/x86_cliptest.S',
- 'x86/mmx_blend.S',
- 'x86/3dnow_xform1.S',
- 'x86/3dnow_xform2.S',
- 'x86/3dnow_xform3.S',
- 'x86/3dnow_xform4.S',
- 'x86/3dnow_normal.S',
- 'x86/sse_xform1.S',
- 'x86/sse_xform2.S',
- 'x86/sse_xform3.S',
- 'x86/sse_xform4.S',
- 'x86/sse_normal.S',
- 'x86/read_rgba_span_x86.S',
- ]
- elif env['machine'] == 'x86_64':
- env.Append(CPPDEFINES = [
- 'USE_X86_64_ASM',
- ])
- mesa_sources += [
- 'x86-64/x86-64.c',
- 'x86-64/xform4.S',
- ]
- elif env['machine'] == 'ppc':
- env.Append(CPPDEFINES = [
- 'USE_PPC_ASM',
- 'USE_VMX_ASM',
- ])
- mesa_sources += [
- 'ppc/common_ppc.c',
- ]
- elif env['machine'] == 'sparc':
- mesa_sources += [
- 'sparc/sparc.c',
- 'sparc/clip.S',
- 'sparc/norm.S',
- 'sparc/xform.S',
- ]
- else:
- pass
-
- # Generate matypes.h
- if env['machine'] in ('x86', 'x86_64'):
- # See http://www.scons.org/wiki/UsingCodeGenerators
- gen_matypes = env.Program(
- target = 'gen_matypes',
- source = 'x86/gen_matypes.c',
- )
- matypes = env.Command(
- 'matypes.h',
- gen_matypes,
- gen_matypes[0].abspath + ' > $TARGET',
- )
- # Add the dir containing the generated header (somewhere inside the
- # build dir) to the include path
- env.Append(CPPPATH = [matypes[0].dir])
-
-#
-# Libraries
-#
-
-mesa = env.ConvenienceLibrary(
- target = 'mesa',
- source = mesa_sources,
-)
-
-env.Alias('mesa', mesa)
-
-Export('mesa')
+#######################################################################
+# SConscript for Mesa
+
+
+Import('*')
+
+env = env.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/mapi',
+ '#/src/glsl',
+ '#/src/mesa',
+])
+
+env.Append(CPPDEFINES = [
+ 'FEATURE_GL=1',
+])
+
+if env['platform'] == 'windows':
+ env.Append(CPPDEFINES = [
+ '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers
+ 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers
+ ])
+ if not env['gles']:
+ # prevent _glapi_* from being declared __declspec(dllimport)
+ env.Append(CPPDEFINES = ['_GLAPI_NO_EXPORTS'])
+else:
+ env.Append(CPPDEFINES = [
+ 'IN_DRI_DRIVER', # enable the remap table (for DRI drivers)
+ ])
+
+#
+# Source files
+#
+
+main_sources = [
+ 'main/api_arrayelt.c',
+ 'main/api_exec.c',
+ 'main/api_loopback.c',
+ 'main/api_noop.c',
+ 'main/api_validate.c',
+ 'main/accum.c',
+ 'main/arbprogram.c',
+ 'main/atifragshader.c',
+ 'main/attrib.c',
+ 'main/arrayobj.c',
+ 'main/blend.c',
+ 'main/bufferobj.c',
+ 'main/buffers.c',
+ 'main/clear.c',
+ 'main/clip.c',
+ 'main/colortab.c',
+ 'main/condrender.c',
+ 'main/context.c',
+ 'main/convolve.c',
+ 'main/cpuinfo.c',
+ 'main/debug.c',
+ 'main/depth.c',
+ 'main/depthstencil.c',
+ 'main/dlist.c',
+ 'main/dlopen.c',
+ 'main/drawpix.c',
+ 'main/drawtex.c',
+ 'main/enable.c',
+ 'main/enums.c',
+ 'main/eval.c',
+ 'main/execmem.c',
+ 'main/extensions.c',
+ 'main/fbobject.c',
+ 'main/feedback.c',
+ 'main/ffvertex_prog.c',
+ 'main/fog.c',
+ 'main/formats.c',
+ 'main/framebuffer.c',
+ 'main/get.c',
+ 'main/getstring.c',
+ 'main/hash.c',
+ 'main/hint.c',
+ 'main/histogram.c',
+ 'main/image.c',
+ 'main/imports.c',
+ 'main/light.c',
+ 'main/lines.c',
+ 'main/matrix.c',
+ 'main/mipmap.c',
+ 'main/mm.c',
+ 'main/multisample.c',
+ 'main/nvprogram.c',
+ 'main/pack.c',
+ 'main/pixel.c',
+ 'main/pixelstore.c',
+ 'main/pixeltransfer.c',
+ 'main/points.c',
+ 'main/polygon.c',
+ 'main/querymatrix.c',
+ 'main/queryobj.c',
+ 'main/rastpos.c',
+ 'main/readpix.c',
+ 'main/remap.c',
+ 'main/renderbuffer.c',
+ 'main/scissor.c',
+ 'main/shaderapi.c',
+ 'main/shaderobj.c',
+ 'main/shared.c',
+ 'main/state.c',
+ 'main/stencil.c',
+ 'main/syncobj.c',
+ 'main/texcompress.c',
+ 'main/texcompress_s3tc.c',
+ 'main/texcompress_fxt1.c',
+ 'main/texenv.c',
+ 'main/texenvprogram.c',
+ 'main/texfetch.c',
+ 'main/texformat.c',
+ 'main/texgen.c',
+ 'main/texgetimage.c',
+ 'main/teximage.c',
+ 'main/texobj.c',
+ 'main/texpal.c',
+ 'main/texparam.c',
+ 'main/texrender.c',
+ 'main/texstate.c',
+ 'main/texstore.c',
+ 'main/transformfeedback.c',
+ 'main/uniforms.c',
+ 'main/varray.c',
+ 'main/version.c',
+ 'main/viewport.c',
+ 'main/vtxfmt.c',
+]
+
+math_sources = [
+ 'math/m_debug_clip.c',
+ 'math/m_debug_norm.c',
+ 'math/m_debug_xform.c',
+ 'math/m_eval.c',
+ 'math/m_matrix.c',
+ 'math/m_translate.c',
+ 'math/m_vector.c',
+ 'math/m_xform.c',
+]
+
+vbo_sources = [
+ 'vbo/vbo_context.c',
+ 'vbo/vbo_exec.c',
+ 'vbo/vbo_exec_api.c',
+ 'vbo/vbo_exec_array.c',
+ 'vbo/vbo_exec_draw.c',
+ 'vbo/vbo_exec_eval.c',
+ 'vbo/vbo_rebase.c',
+ 'vbo/vbo_split.c',
+ 'vbo/vbo_split_copy.c',
+ 'vbo/vbo_split_inplace.c',
+ 'vbo/vbo_save.c',
+ 'vbo/vbo_save_api.c',
+ 'vbo/vbo_save_draw.c',
+ 'vbo/vbo_save_loopback.c',
+]
+
+vf_sources = [
+ 'vf/vf.c',
+ 'vf/vf_generic.c',
+ 'vf/vf_sse.c',
+]
+
+statetracker_sources = [
+ 'state_tracker/st_atom.c',
+ 'state_tracker/st_atom_blend.c',
+ 'state_tracker/st_atom_clip.c',
+ 'state_tracker/st_atom_constbuf.c',
+ 'state_tracker/st_atom_depth.c',
+ 'state_tracker/st_atom_framebuffer.c',
+ 'state_tracker/st_atom_msaa.c',
+ 'state_tracker/st_atom_pixeltransfer.c',
+ 'state_tracker/st_atom_sampler.c',
+ 'state_tracker/st_atom_scissor.c',
+ 'state_tracker/st_atom_shader.c',
+ 'state_tracker/st_atom_rasterizer.c',
+ 'state_tracker/st_atom_stipple.c',
+ 'state_tracker/st_atom_texture.c',
+ 'state_tracker/st_atom_viewport.c',
+ 'state_tracker/st_cb_accum.c',
+ 'state_tracker/st_cb_bitmap.c',
+ 'state_tracker/st_cb_blit.c',
+ 'state_tracker/st_cb_bufferobjects.c',
+ 'state_tracker/st_cb_clear.c',
+ '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',
+ 'state_tracker/st_cb_program.c',
+ 'state_tracker/st_cb_queryobj.c',
+ 'state_tracker/st_cb_rasterpos.c',
+ 'state_tracker/st_cb_readpixels.c',
+ 'state_tracker/st_cb_strings.c',
+ 'state_tracker/st_cb_texture.c',
+ 'state_tracker/st_cb_viewport.c',
+ 'state_tracker/st_cb_xformfb.c',
+ 'state_tracker/st_context.c',
+ 'state_tracker/st_debug.c',
+ 'state_tracker/st_draw.c',
+ 'state_tracker/st_draw_feedback.c',
+ 'state_tracker/st_extensions.c',
+ 'state_tracker/st_format.c',
+ 'state_tracker/st_gen_mipmap.c',
+ 'state_tracker/st_manager.c',
+ 'state_tracker/st_mesa_to_tgsi.c',
+ 'state_tracker/st_program.c',
+ 'state_tracker/st_texture.c',
+]
+
+program_sources = [
+ 'program/arbprogparse.c',
+ 'program/hash_table.c',
+ 'program/ir_to_mesa.cpp',
+ 'program/lex.yy.c',
+ 'program/nvfragparse.c',
+ 'program/nvvertparse.c',
+ 'program/program.c',
+ 'program/program_parse.tab.c',
+ 'program/program_parse_extra.c',
+ 'program/prog_cache.c',
+ 'program/prog_execute.c',
+ 'program/prog_instruction.c',
+ 'program/prog_noise.c',
+ 'program/prog_optimize.c',
+ 'program/prog_parameter.c',
+ 'program/prog_parameter_layout.c',
+ 'program/prog_print.c',
+ 'program/prog_statevars.c',
+ 'program/prog_uniform.c',
+ 'program/programopt.c',
+ 'program/sampler.cpp',
+ 'program/symbol_table.c',
+]
+
+mesa_sources = (
+ main_sources +
+ math_sources +
+ program_sources +
+ vbo_sources +
+ vf_sources +
+ statetracker_sources
+)
+
+if env['gles']:
+ from sys import executable as python_cmd
+
+ env.Append(CPPDEFINES = ['FEATURE_ES1=1', 'FEATURE_ES2=1'])
+
+ # generate GLES sources
+ gles_sources = []
+ gles_sources += env.CodeGenerate(
+ target = 'main/api_exec_es1.c',
+ script = 'main/es_generator.py',
+ source = 'main/APIspec.xml',
+ command = python_cmd + ' $SCRIPT -S $SOURCE -V GLES1.1 > $TARGET'
+ )
+ gles_sources += env.CodeGenerate(
+ target = 'main/api_exec_es2.c',
+ script = 'main/es_generator.py',
+ source = 'main/APIspec.xml',
+ command = python_cmd + ' $SCRIPT -S $SOURCE -V GLES2.0 > $TARGET'
+ )
+
+ # generate GLES headers
+ GLAPI = '#src/mapi/glapi/'
+ gles_headers = []
+ gles_headers += env.CodeGenerate(
+ target = 'es1api/main/glapidispatch.h',
+ script = GLAPI + 'gen/gl_table.py',
+ source = GLAPI + 'gen-es/es1_API.xml',
+ command = python_cmd + ' $SCRIPT -c -m remap_table -f $SOURCE > $TARGET',
+ )
+ gles_headers += env.CodeGenerate(
+ target = 'es1api/main/remap_helper.h',
+ script = GLAPI + 'gen/remap_helper.py',
+ source = GLAPI + 'gen-es/es1_API.xml',
+ command = python_cmd + ' $SCRIPT -f $SOURCE > $TARGET',
+ )
+ gles_headers += env.CodeGenerate(
+ target = 'es2api/main/glapidispatch.h',
+ script = GLAPI + 'gen/gl_table.py',
+ source = GLAPI + 'gen-es/es2_API.xml',
+ command = python_cmd + ' $SCRIPT -c -m remap_table -f $SOURCE > $TARGET',
+ )
+ gles_headers += env.CodeGenerate(
+ target = 'es2api/main/remap_helper.h',
+ script = GLAPI + 'gen/remap_helper.py',
+ source = GLAPI + 'gen-es/es2_API.xml',
+ command = python_cmd + ' $SCRIPT -f $SOURCE > $TARGET',
+ )
+
+ env.Depends(gles_sources, gles_headers)
+
+ # gles_sources #include gles_headers with full path
+ env.Append(CPPPATH = [gles_headers[0].dir.up().up()])
+
+ mesa_sources += gles_sources
+
+#
+# Assembly sources
+#
+if env['gcc'] and env['platform'] != 'windows':
+ if env['machine'] == 'x86':
+ env.Append(CPPDEFINES = [
+ 'USE_X86_ASM',
+ 'USE_MMX_ASM',
+ 'USE_3DNOW_ASM',
+ 'USE_SSE_ASM',
+ ])
+ mesa_sources += [
+ 'x86/common_x86.c',
+ 'x86/x86_xform.c',
+ 'x86/3dnow.c',
+ 'x86/sse.c',
+ 'x86/common_x86_asm.S',
+ 'x86/x86_xform2.S',
+ 'x86/x86_xform3.S',
+ 'x86/x86_xform4.S',
+ 'x86/x86_cliptest.S',
+ 'x86/mmx_blend.S',
+ 'x86/3dnow_xform1.S',
+ 'x86/3dnow_xform2.S',
+ 'x86/3dnow_xform3.S',
+ 'x86/3dnow_xform4.S',
+ 'x86/3dnow_normal.S',
+ 'x86/sse_xform1.S',
+ 'x86/sse_xform2.S',
+ 'x86/sse_xform3.S',
+ 'x86/sse_xform4.S',
+ 'x86/sse_normal.S',
+ 'x86/read_rgba_span_x86.S',
+ ]
+ elif env['machine'] == 'x86_64':
+ env.Append(CPPDEFINES = [
+ 'USE_X86_64_ASM',
+ ])
+ mesa_sources += [
+ 'x86-64/x86-64.c',
+ 'x86-64/xform4.S',
+ ]
+ elif env['machine'] == 'ppc':
+ env.Append(CPPDEFINES = [
+ 'USE_PPC_ASM',
+ 'USE_VMX_ASM',
+ ])
+ mesa_sources += [
+ 'ppc/common_ppc.c',
+ ]
+ elif env['machine'] == 'sparc':
+ mesa_sources += [
+ 'sparc/sparc.c',
+ 'sparc/clip.S',
+ 'sparc/norm.S',
+ 'sparc/xform.S',
+ ]
+ else:
+ pass
+
+ # Generate matypes.h
+ if env['machine'] in ('x86', 'x86_64'):
+ # See http://www.scons.org/wiki/UsingCodeGenerators
+ gen_matypes = env.Program(
+ target = 'gen_matypes',
+ source = 'x86/gen_matypes.c',
+ )
+ matypes = env.Command(
+ 'matypes.h',
+ gen_matypes,
+ gen_matypes[0].abspath + ' > $TARGET',
+ )
+ # Add the dir containing the generated header (somewhere inside the
+ # build dir) to the include path
+ env.Append(CPPPATH = [matypes[0].dir])
+
+#
+# Libraries
+#
+
+mesa = env.ConvenienceLibrary(
+ target = 'mesa',
+ source = mesa_sources,
+)
+
+env.Alias('mesa', mesa)
+
+Export('mesa')
diff --git a/mesalib/src/mesa/main/arrayobj.c b/mesalib/src/mesa/main/arrayobj.c
index 2d85b88ae..460102233 100644
--- a/mesalib/src/mesa/main/arrayobj.c
+++ b/mesalib/src/mesa/main/arrayobj.c
@@ -1,578 +1,578 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.6
- *
- * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
- * (C) Copyright IBM Corporation 2006
- * 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 OR IBM 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 arrayobj.c
- * Functions for the GL_APPLE_vertex_array_object extension.
- *
- * \todo
- * The code in this file borrows a lot from bufferobj.c. There's a certain
- * amount of cruft left over from that origin that may be unnecessary.
- *
- * \author Ian Romanick <idr@us.ibm.com>
- * \author Brian Paul
- */
-
-
-#include "glheader.h"
-#include "hash.h"
-#include "imports.h"
-#include "context.h"
-#include "mfeatures.h"
-#if FEATURE_ARB_vertex_buffer_object
-#include "bufferobj.h"
-#endif
-#include "arrayobj.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "main/dispatch.h"
-
-
-/**
- * Look up the array object for the given ID.
- *
- * \returns
- * Either a pointer to the array object with the specified ID or \c NULL for
- * a non-existent ID. The spec defines ID 0 as being technically
- * non-existent.
- */
-
-static INLINE struct gl_array_object *
-lookup_arrayobj(struct gl_context *ctx, GLuint id)
-{
- if (id == 0)
- return NULL;
- else
- return (struct gl_array_object *)
- _mesa_HashLookup(ctx->Array.Objects, id);
-}
-
-
-/**
- * For all the vertex arrays in the array object, unbind any pointers
- * to any buffer objects (VBOs).
- * This is done just prior to array object destruction.
- */
-static void
-unbind_array_object_vbos(struct gl_context *ctx, struct gl_array_object *obj)
-{
- GLuint i;
-
- _mesa_reference_buffer_object(ctx, &obj->Vertex.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &obj->Weight.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &obj->Normal.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &obj->Color.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &obj->SecondaryColor.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &obj->FogCoord.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &obj->Index.BufferObj, NULL);
- _mesa_reference_buffer_object(ctx, &obj->EdgeFlag.BufferObj, NULL);
-
- for (i = 0; i < Elements(obj->TexCoord); i++)
- _mesa_reference_buffer_object(ctx, &obj->TexCoord[i].BufferObj, NULL);
-
- for (i = 0; i < Elements(obj->VertexAttrib); i++)
- _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL);
-
-#if FEATURE_point_size_array
- _mesa_reference_buffer_object(ctx, &obj->PointSize.BufferObj, NULL);
-#endif
-}
-
-
-/**
- * Allocate and initialize a new vertex array object.
- *
- * This function is intended to be called via
- * \c dd_function_table::NewArrayObject.
- */
-struct gl_array_object *
-_mesa_new_array_object( struct gl_context *ctx, GLuint name )
-{
- struct gl_array_object *obj = CALLOC_STRUCT(gl_array_object);
- if (obj)
- _mesa_initialize_array_object(ctx, obj, name);
- return obj;
-}
-
-
-/**
- * Delete an array object.
- *
- * This function is intended to be called via
- * \c dd_function_table::DeleteArrayObject.
- */
-void
-_mesa_delete_array_object( struct gl_context *ctx, struct gl_array_object *obj )
-{
- (void) ctx;
- unbind_array_object_vbos(ctx, obj);
- _glthread_DESTROY_MUTEX(obj->Mutex);
- free(obj);
-}
-
-
-/**
- * Set ptr to arrayObj w/ reference counting.
- */
-void
-_mesa_reference_array_object(struct gl_context *ctx,
- struct gl_array_object **ptr,
- struct gl_array_object *arrayObj)
-{
- if (*ptr == arrayObj)
- return;
-
- if (*ptr) {
- /* Unreference the old array object */
- GLboolean deleteFlag = GL_FALSE;
- struct gl_array_object *oldObj = *ptr;
-
- _glthread_LOCK_MUTEX(oldObj->Mutex);
- ASSERT(oldObj->RefCount > 0);
- oldObj->RefCount--;
-#if 0
- printf("ArrayObj %p %d DECR to %d\n",
- (void *) oldObj, oldObj->Name, oldObj->RefCount);
-#endif
- deleteFlag = (oldObj->RefCount == 0);
- _glthread_UNLOCK_MUTEX(oldObj->Mutex);
-
- if (deleteFlag) {
- ASSERT(ctx->Driver.DeleteArrayObject);
- ctx->Driver.DeleteArrayObject(ctx, oldObj);
- }
-
- *ptr = NULL;
- }
- ASSERT(!*ptr);
-
- if (arrayObj) {
- /* reference new array object */
- _glthread_LOCK_MUTEX(arrayObj->Mutex);
- if (arrayObj->RefCount == 0) {
- /* this array's being deleted (look just above) */
- /* Not sure this can every really happen. Warn if it does. */
- _mesa_problem(NULL, "referencing deleted array object");
- *ptr = NULL;
- }
- else {
- arrayObj->RefCount++;
-#if 0
- printf("ArrayObj %p %d INCR to %d\n",
- (void *) arrayObj, arrayObj->Name, arrayObj->RefCount);
-#endif
- *ptr = arrayObj;
- }
- _glthread_UNLOCK_MUTEX(arrayObj->Mutex);
- }
-}
-
-
-
-static void
-init_array(struct gl_context *ctx,
- struct gl_client_array *array, GLint size, GLint type)
-{
- array->Size = size;
- array->Type = type;
- array->Format = GL_RGBA; /* only significant for GL_EXT_vertex_array_bgra */
- array->Stride = 0;
- array->StrideB = 0;
- array->Ptr = NULL;
- array->Enabled = GL_FALSE;
- array->Normalized = GL_FALSE;
-#if FEATURE_ARB_vertex_buffer_object
- /* Vertex array buffers */
- _mesa_reference_buffer_object(ctx, &array->BufferObj,
- ctx->Shared->NullBufferObj);
-#endif
-}
-
-
-/**
- * Initialize a gl_array_object's arrays.
- */
-void
-_mesa_initialize_array_object( struct gl_context *ctx,
- struct gl_array_object *obj,
- GLuint name )
-{
- GLuint i;
-
- obj->Name = name;
-
- _glthread_INIT_MUTEX(obj->Mutex);
- obj->RefCount = 1;
-
- /* Init the individual arrays */
- init_array(ctx, &obj->Vertex, 4, GL_FLOAT);
- init_array(ctx, &obj->Weight, 1, GL_FLOAT);
- init_array(ctx, &obj->Normal, 3, GL_FLOAT);
- init_array(ctx, &obj->Color, 4, GL_FLOAT);
- init_array(ctx, &obj->SecondaryColor, 4, GL_FLOAT);
- init_array(ctx, &obj->FogCoord, 1, GL_FLOAT);
- init_array(ctx, &obj->Index, 1, GL_FLOAT);
- for (i = 0; i < Elements(obj->TexCoord); i++) {
- init_array(ctx, &obj->TexCoord[i], 4, GL_FLOAT);
- }
- init_array(ctx, &obj->EdgeFlag, 1, GL_BOOL);
- for (i = 0; i < Elements(obj->VertexAttrib); i++) {
- init_array(ctx, &obj->VertexAttrib[i], 4, GL_FLOAT);
- }
-
-#if FEATURE_point_size_array
- init_array(ctx, &obj->PointSize, 1, GL_FLOAT);
-#endif
-}
-
-
-/**
- * Add the given array object to the array object pool.
- */
-static void
-save_array_object( struct gl_context *ctx, struct gl_array_object *obj )
-{
- if (obj->Name > 0) {
- /* insert into hash table */
- _mesa_HashInsert(ctx->Array.Objects, obj->Name, obj);
- }
-}
-
-
-/**
- * Remove the given array object from the array object pool.
- * Do not deallocate the array object though.
- */
-static void
-remove_array_object( struct gl_context *ctx, struct gl_array_object *obj )
-{
- if (obj->Name > 0) {
- /* remove from hash table */
- _mesa_HashRemove(ctx->Array.Objects, obj->Name);
- }
-}
-
-
-
-/**
- * Compute the index of the last array element that can be safely accessed
- * in a vertex array. We can really only do this when the array lives in
- * a VBO.
- * The array->_MaxElement field will be updated.
- * Later in glDrawArrays/Elements/etc we can do some bounds checking.
- */
-static void
-compute_max_element(struct gl_client_array *array)
-{
- if (array->BufferObj->Name) {
- /* Compute the max element we can access in the VBO without going
- * out of bounds.
- */
- array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size
- - (GLsizeiptrARB) array->Ptr + array->StrideB
- - array->_ElementSize) / array->StrideB;
- if (0)
- printf("%s Object %u Size %u MaxElement %u\n",
- __FUNCTION__,
- array->BufferObj->Name,
- (GLuint) array->BufferObj->Size,
- array->_MaxElement);
- }
- else {
- /* user-space array, no idea how big it is */
- array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */
- }
-}
-
-
-/**
- * Helper for update_arrays().
- * \return min(current min, array->_MaxElement).
- */
-static GLuint
-update_min(GLuint min, struct gl_client_array *array)
-{
- compute_max_element(array);
- if (array->Enabled)
- return MIN2(min, array->_MaxElement);
- else
- return min;
-}
-
-
-/**
- * Examine vertex arrays to update the gl_array_object::_MaxElement field.
- */
-void
-_mesa_update_array_object_max_element(struct gl_context *ctx,
- struct gl_array_object *arrayObj)
-{
- GLuint i, min = ~0;
-
- min = update_min(min, &arrayObj->Vertex);
- min = update_min(min, &arrayObj->Weight);
- min = update_min(min, &arrayObj->Normal);
- min = update_min(min, &arrayObj->Color);
- min = update_min(min, &arrayObj->SecondaryColor);
- min = update_min(min, &arrayObj->FogCoord);
- min = update_min(min, &arrayObj->Index);
- min = update_min(min, &arrayObj->EdgeFlag);
-#if FEATURE_point_size_array
- min = update_min(min, &arrayObj->PointSize);
-#endif
- for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
- min = update_min(min, &arrayObj->TexCoord[i]);
- for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
- min = update_min(min, &arrayObj->VertexAttrib[i]);
-
- /* _MaxElement is one past the last legal array element */
- arrayObj->_MaxElement = min;
-}
-
-
-/**********************************************************************/
-/* API Functions */
-/**********************************************************************/
-
-
-/**
- * Helper for _mesa_BindVertexArray() and _mesa_BindVertexArrayAPPLE().
- * \param genRequired specifies behavour when id was not generated with
- * glGenVertexArrays().
- */
-static void
-bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired)
-{
- struct gl_array_object * const oldObj = ctx->Array.ArrayObj;
- struct gl_array_object *newObj = NULL;
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- ASSERT(oldObj != NULL);
-
- if ( oldObj->Name == id )
- return; /* rebinding the same array object- no change */
-
- /*
- * Get pointer to new array object (newObj)
- */
- if (id == 0) {
- /* The spec says there is no array object named 0, but we use
- * one internally because it simplifies things.
- */
- newObj = ctx->Array.DefaultArrayObj;
- }
- else {
- /* non-default array object */
- newObj = lookup_arrayobj(ctx, id);
- if (!newObj) {
- if (genRequired) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBindVertexArray(id)");
- return;
- }
-
- /* For APPLE version, generate a new array object now */
- newObj = (*ctx->Driver.NewArrayObject)(ctx, id);
- if (!newObj) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE");
- return;
- }
- save_array_object(ctx, newObj);
- }
- }
-
- ctx->NewState |= _NEW_ARRAY;
- ctx->Array.NewState |= _NEW_ARRAY_ALL;
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, newObj);
-
- /* Pass BindVertexArray call to device driver */
- if (ctx->Driver.BindArrayObject && newObj)
- ctx->Driver.BindArrayObject(ctx, newObj);
-}
-
-
-/**
- * ARB version of glBindVertexArray()
- * This function behaves differently from glBindVertexArrayAPPLE() in
- * that this function requires all ids to have been previously generated
- * by glGenVertexArrays[APPLE]().
- */
-void GLAPIENTRY
-_mesa_BindVertexArray( GLuint id )
-{
- GET_CURRENT_CONTEXT(ctx);
- bind_vertex_array(ctx, id, GL_TRUE);
-}
-
-
-/**
- * Bind a new array.
- *
- * \todo
- * The binding could be done more efficiently by comparing the non-NULL
- * pointers in the old and new objects. The only arrays that are "dirty" are
- * the ones that are non-NULL in either object.
- */
-void GLAPIENTRY
-_mesa_BindVertexArrayAPPLE( GLuint id )
-{
- GET_CURRENT_CONTEXT(ctx);
- bind_vertex_array(ctx, id, GL_FALSE);
-}
-
-
-/**
- * Delete a set of array objects.
- *
- * \param n Number of array objects to delete.
- * \param ids Array of \c n array object IDs.
- */
-void GLAPIENTRY
-_mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLsizei i;
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteVertexArrayAPPLE(n)");
- return;
- }
-
- for (i = 0; i < n; i++) {
- struct gl_array_object *obj = lookup_arrayobj(ctx, ids[i]);
-
- if ( obj != NULL ) {
- ASSERT( obj->Name == ids[i] );
-
- /* If the array object is currently bound, the spec says "the binding
- * for that object reverts to zero and the default vertex array
- * becomes current."
- */
- if ( obj == ctx->Array.ArrayObj ) {
- CALL_BindVertexArrayAPPLE( ctx->Exec, (0) );
- }
-
- /* The ID is immediately freed for re-use */
- remove_array_object(ctx, obj);
-
- /* Unreference the array object.
- * If refcount hits zero, the object will be deleted.
- */
- _mesa_reference_array_object(ctx, &obj, NULL);
- }
- }
-}
-
-
-/**
- * Generate a set of unique array object IDs and store them in \c arrays.
- * Helper for _mesa_GenVertexArrays[APPLE]() functions below.
- * \param n Number of IDs to generate.
- * \param arrays Array of \c n locations to store the IDs.
- * \param vboOnly Will arrays have to reside in VBOs?
- */
-static void
-gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays, GLboolean vboOnly)
-{
- GLuint first;
- GLint i;
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenVertexArraysAPPLE");
- return;
- }
-
- if (!arrays) {
- return;
- }
-
- first = _mesa_HashFindFreeKeyBlock(ctx->Array.Objects, n);
-
- /* Allocate new, empty array objects and return identifiers */
- for (i = 0; i < n; i++) {
- struct gl_array_object *obj;
- GLuint name = first + i;
-
- obj = (*ctx->Driver.NewArrayObject)( ctx, name );
- if (!obj) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE");
- return;
- }
- obj->VBOonly = vboOnly;
- save_array_object(ctx, obj);
- arrays[i] = first + i;
- }
-}
-
-
-/**
- * ARB version of glGenVertexArrays()
- * All arrays will be required to live in VBOs.
- */
-void GLAPIENTRY
-_mesa_GenVertexArrays(GLsizei n, GLuint *arrays)
-{
- GET_CURRENT_CONTEXT(ctx);
- gen_vertex_arrays(ctx, n, arrays, GL_TRUE);
-}
-
-
-/**
- * APPLE version of glGenVertexArraysAPPLE()
- * Arrays may live in VBOs or ordinary memory.
- */
-void GLAPIENTRY
-_mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays)
-{
- GET_CURRENT_CONTEXT(ctx);
- gen_vertex_arrays(ctx, n, arrays, GL_FALSE);
-}
-
-
-/**
- * Determine if ID is the name of an array object.
- *
- * \param id ID of the potential array object.
- * \return \c GL_TRUE if \c id is the name of a array object,
- * \c GL_FALSE otherwise.
- */
-GLboolean GLAPIENTRY
-_mesa_IsVertexArrayAPPLE( GLuint id )
-{
- struct gl_array_object * obj;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
-
- if (id == 0)
- return GL_FALSE;
-
- obj = lookup_arrayobj(ctx, id);
-
- return (obj != NULL) ? GL_TRUE : GL_FALSE;
-}
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.6
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * (C) Copyright IBM Corporation 2006
+ * 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 OR IBM 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 arrayobj.c
+ * Functions for the GL_APPLE_vertex_array_object extension.
+ *
+ * \todo
+ * The code in this file borrows a lot from bufferobj.c. There's a certain
+ * amount of cruft left over from that origin that may be unnecessary.
+ *
+ * \author Ian Romanick <idr@us.ibm.com>
+ * \author Brian Paul
+ */
+
+
+#include "glheader.h"
+#include "hash.h"
+#include "imports.h"
+#include "context.h"
+#include "mfeatures.h"
+#if FEATURE_ARB_vertex_buffer_object
+#include "bufferobj.h"
+#endif
+#include "arrayobj.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "main/dispatch.h"
+
+
+/**
+ * Look up the array object for the given ID.
+ *
+ * \returns
+ * Either a pointer to the array object with the specified ID or \c NULL for
+ * a non-existent ID. The spec defines ID 0 as being technically
+ * non-existent.
+ */
+
+static INLINE struct gl_array_object *
+lookup_arrayobj(struct gl_context *ctx, GLuint id)
+{
+ if (id == 0)
+ return NULL;
+ else
+ return (struct gl_array_object *)
+ _mesa_HashLookup(ctx->Array.Objects, id);
+}
+
+
+/**
+ * For all the vertex arrays in the array object, unbind any pointers
+ * to any buffer objects (VBOs).
+ * This is done just prior to array object destruction.
+ */
+static void
+unbind_array_object_vbos(struct gl_context *ctx, struct gl_array_object *obj)
+{
+ GLuint i;
+
+ _mesa_reference_buffer_object(ctx, &obj->Vertex.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &obj->Weight.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &obj->Normal.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &obj->Color.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &obj->SecondaryColor.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &obj->FogCoord.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &obj->Index.BufferObj, NULL);
+ _mesa_reference_buffer_object(ctx, &obj->EdgeFlag.BufferObj, NULL);
+
+ for (i = 0; i < Elements(obj->TexCoord); i++)
+ _mesa_reference_buffer_object(ctx, &obj->TexCoord[i].BufferObj, NULL);
+
+ for (i = 0; i < Elements(obj->VertexAttrib); i++)
+ _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL);
+
+#if FEATURE_point_size_array
+ _mesa_reference_buffer_object(ctx, &obj->PointSize.BufferObj, NULL);
+#endif
+}
+
+
+/**
+ * Allocate and initialize a new vertex array object.
+ *
+ * This function is intended to be called via
+ * \c dd_function_table::NewArrayObject.
+ */
+struct gl_array_object *
+_mesa_new_array_object( struct gl_context *ctx, GLuint name )
+{
+ struct gl_array_object *obj = CALLOC_STRUCT(gl_array_object);
+ if (obj)
+ _mesa_initialize_array_object(ctx, obj, name);
+ return obj;
+}
+
+
+/**
+ * Delete an array object.
+ *
+ * This function is intended to be called via
+ * \c dd_function_table::DeleteArrayObject.
+ */
+void
+_mesa_delete_array_object( struct gl_context *ctx, struct gl_array_object *obj )
+{
+ (void) ctx;
+ unbind_array_object_vbos(ctx, obj);
+ _glthread_DESTROY_MUTEX(obj->Mutex);
+ free(obj);
+}
+
+
+/**
+ * Set ptr to arrayObj w/ reference counting.
+ */
+void
+_mesa_reference_array_object(struct gl_context *ctx,
+ struct gl_array_object **ptr,
+ struct gl_array_object *arrayObj)
+{
+ if (*ptr == arrayObj)
+ return;
+
+ if (*ptr) {
+ /* Unreference the old array object */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_array_object *oldObj = *ptr;
+
+ _glthread_LOCK_MUTEX(oldObj->Mutex);
+ ASSERT(oldObj->RefCount > 0);
+ oldObj->RefCount--;
+#if 0
+ printf("ArrayObj %p %d DECR to %d\n",
+ (void *) oldObj, oldObj->Name, oldObj->RefCount);
+#endif
+ deleteFlag = (oldObj->RefCount == 0);
+ _glthread_UNLOCK_MUTEX(oldObj->Mutex);
+
+ if (deleteFlag) {
+ ASSERT(ctx->Driver.DeleteArrayObject);
+ ctx->Driver.DeleteArrayObject(ctx, oldObj);
+ }
+
+ *ptr = NULL;
+ }
+ ASSERT(!*ptr);
+
+ if (arrayObj) {
+ /* reference new array object */
+ _glthread_LOCK_MUTEX(arrayObj->Mutex);
+ if (arrayObj->RefCount == 0) {
+ /* this array's being deleted (look just above) */
+ /* Not sure this can every really happen. Warn if it does. */
+ _mesa_problem(NULL, "referencing deleted array object");
+ *ptr = NULL;
+ }
+ else {
+ arrayObj->RefCount++;
+#if 0
+ printf("ArrayObj %p %d INCR to %d\n",
+ (void *) arrayObj, arrayObj->Name, arrayObj->RefCount);
+#endif
+ *ptr = arrayObj;
+ }
+ _glthread_UNLOCK_MUTEX(arrayObj->Mutex);
+ }
+}
+
+
+
+static void
+init_array(struct gl_context *ctx,
+ struct gl_client_array *array, GLint size, GLint type)
+{
+ array->Size = size;
+ array->Type = type;
+ array->Format = GL_RGBA; /* only significant for GL_EXT_vertex_array_bgra */
+ array->Stride = 0;
+ array->StrideB = 0;
+ array->Ptr = NULL;
+ array->Enabled = GL_FALSE;
+ array->Normalized = GL_FALSE;
+#if FEATURE_ARB_vertex_buffer_object
+ /* Vertex array buffers */
+ _mesa_reference_buffer_object(ctx, &array->BufferObj,
+ ctx->Shared->NullBufferObj);
+#endif
+}
+
+
+/**
+ * Initialize a gl_array_object's arrays.
+ */
+void
+_mesa_initialize_array_object( struct gl_context *ctx,
+ struct gl_array_object *obj,
+ GLuint name )
+{
+ GLuint i;
+
+ obj->Name = name;
+
+ _glthread_INIT_MUTEX(obj->Mutex);
+ obj->RefCount = 1;
+
+ /* Init the individual arrays */
+ init_array(ctx, &obj->Vertex, 4, GL_FLOAT);
+ init_array(ctx, &obj->Weight, 1, GL_FLOAT);
+ init_array(ctx, &obj->Normal, 3, GL_FLOAT);
+ init_array(ctx, &obj->Color, 4, GL_FLOAT);
+ init_array(ctx, &obj->SecondaryColor, 3, GL_FLOAT);
+ init_array(ctx, &obj->FogCoord, 1, GL_FLOAT);
+ init_array(ctx, &obj->Index, 1, GL_FLOAT);
+ for (i = 0; i < Elements(obj->TexCoord); i++) {
+ init_array(ctx, &obj->TexCoord[i], 4, GL_FLOAT);
+ }
+ init_array(ctx, &obj->EdgeFlag, 1, GL_BOOL);
+ for (i = 0; i < Elements(obj->VertexAttrib); i++) {
+ init_array(ctx, &obj->VertexAttrib[i], 4, GL_FLOAT);
+ }
+
+#if FEATURE_point_size_array
+ init_array(ctx, &obj->PointSize, 1, GL_FLOAT);
+#endif
+}
+
+
+/**
+ * Add the given array object to the array object pool.
+ */
+static void
+save_array_object( struct gl_context *ctx, struct gl_array_object *obj )
+{
+ if (obj->Name > 0) {
+ /* insert into hash table */
+ _mesa_HashInsert(ctx->Array.Objects, obj->Name, obj);
+ }
+}
+
+
+/**
+ * Remove the given array object from the array object pool.
+ * Do not deallocate the array object though.
+ */
+static void
+remove_array_object( struct gl_context *ctx, struct gl_array_object *obj )
+{
+ if (obj->Name > 0) {
+ /* remove from hash table */
+ _mesa_HashRemove(ctx->Array.Objects, obj->Name);
+ }
+}
+
+
+
+/**
+ * Compute the index of the last array element that can be safely accessed
+ * in a vertex array. We can really only do this when the array lives in
+ * a VBO.
+ * The array->_MaxElement field will be updated.
+ * Later in glDrawArrays/Elements/etc we can do some bounds checking.
+ */
+static void
+compute_max_element(struct gl_client_array *array)
+{
+ if (array->BufferObj->Name) {
+ /* Compute the max element we can access in the VBO without going
+ * out of bounds.
+ */
+ array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size
+ - (GLsizeiptrARB) array->Ptr + array->StrideB
+ - array->_ElementSize) / array->StrideB;
+ if (0)
+ printf("%s Object %u Size %u MaxElement %u\n",
+ __FUNCTION__,
+ array->BufferObj->Name,
+ (GLuint) array->BufferObj->Size,
+ array->_MaxElement);
+ }
+ else {
+ /* user-space array, no idea how big it is */
+ array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */
+ }
+}
+
+
+/**
+ * Helper for update_arrays().
+ * \return min(current min, array->_MaxElement).
+ */
+static GLuint
+update_min(GLuint min, struct gl_client_array *array)
+{
+ compute_max_element(array);
+ if (array->Enabled)
+ return MIN2(min, array->_MaxElement);
+ else
+ return min;
+}
+
+
+/**
+ * Examine vertex arrays to update the gl_array_object::_MaxElement field.
+ */
+void
+_mesa_update_array_object_max_element(struct gl_context *ctx,
+ struct gl_array_object *arrayObj)
+{
+ GLuint i, min = ~0;
+
+ min = update_min(min, &arrayObj->Vertex);
+ min = update_min(min, &arrayObj->Weight);
+ min = update_min(min, &arrayObj->Normal);
+ min = update_min(min, &arrayObj->Color);
+ min = update_min(min, &arrayObj->SecondaryColor);
+ min = update_min(min, &arrayObj->FogCoord);
+ min = update_min(min, &arrayObj->Index);
+ min = update_min(min, &arrayObj->EdgeFlag);
+#if FEATURE_point_size_array
+ min = update_min(min, &arrayObj->PointSize);
+#endif
+ for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
+ min = update_min(min, &arrayObj->TexCoord[i]);
+ for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
+ min = update_min(min, &arrayObj->VertexAttrib[i]);
+
+ /* _MaxElement is one past the last legal array element */
+ arrayObj->_MaxElement = min;
+}
+
+
+/**********************************************************************/
+/* API Functions */
+/**********************************************************************/
+
+
+/**
+ * Helper for _mesa_BindVertexArray() and _mesa_BindVertexArrayAPPLE().
+ * \param genRequired specifies behavour when id was not generated with
+ * glGenVertexArrays().
+ */
+static void
+bind_vertex_array(struct gl_context *ctx, GLuint id, GLboolean genRequired)
+{
+ struct gl_array_object * const oldObj = ctx->Array.ArrayObj;
+ struct gl_array_object *newObj = NULL;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ ASSERT(oldObj != NULL);
+
+ if ( oldObj->Name == id )
+ return; /* rebinding the same array object- no change */
+
+ /*
+ * Get pointer to new array object (newObj)
+ */
+ if (id == 0) {
+ /* The spec says there is no array object named 0, but we use
+ * one internally because it simplifies things.
+ */
+ newObj = ctx->Array.DefaultArrayObj;
+ }
+ else {
+ /* non-default array object */
+ newObj = lookup_arrayobj(ctx, id);
+ if (!newObj) {
+ if (genRequired) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindVertexArray(id)");
+ return;
+ }
+
+ /* For APPLE version, generate a new array object now */
+ newObj = (*ctx->Driver.NewArrayObject)(ctx, id);
+ if (!newObj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE");
+ return;
+ }
+ save_array_object(ctx, newObj);
+ }
+ }
+
+ ctx->NewState |= _NEW_ARRAY;
+ ctx->Array.NewState |= _NEW_ARRAY_ALL;
+ _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, newObj);
+
+ /* Pass BindVertexArray call to device driver */
+ if (ctx->Driver.BindArrayObject && newObj)
+ ctx->Driver.BindArrayObject(ctx, newObj);
+}
+
+
+/**
+ * ARB version of glBindVertexArray()
+ * This function behaves differently from glBindVertexArrayAPPLE() in
+ * that this function requires all ids to have been previously generated
+ * by glGenVertexArrays[APPLE]().
+ */
+void GLAPIENTRY
+_mesa_BindVertexArray( GLuint id )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ bind_vertex_array(ctx, id, GL_TRUE);
+}
+
+
+/**
+ * Bind a new array.
+ *
+ * \todo
+ * The binding could be done more efficiently by comparing the non-NULL
+ * pointers in the old and new objects. The only arrays that are "dirty" are
+ * the ones that are non-NULL in either object.
+ */
+void GLAPIENTRY
+_mesa_BindVertexArrayAPPLE( GLuint id )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ bind_vertex_array(ctx, id, GL_FALSE);
+}
+
+
+/**
+ * Delete a set of array objects.
+ *
+ * \param n Number of array objects to delete.
+ * \param ids Array of \c n array object IDs.
+ */
+void GLAPIENTRY
+_mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLsizei i;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteVertexArrayAPPLE(n)");
+ return;
+ }
+
+ for (i = 0; i < n; i++) {
+ struct gl_array_object *obj = lookup_arrayobj(ctx, ids[i]);
+
+ if ( obj != NULL ) {
+ ASSERT( obj->Name == ids[i] );
+
+ /* If the array object is currently bound, the spec says "the binding
+ * for that object reverts to zero and the default vertex array
+ * becomes current."
+ */
+ if ( obj == ctx->Array.ArrayObj ) {
+ CALL_BindVertexArrayAPPLE( ctx->Exec, (0) );
+ }
+
+ /* The ID is immediately freed for re-use */
+ remove_array_object(ctx, obj);
+
+ /* Unreference the array object.
+ * If refcount hits zero, the object will be deleted.
+ */
+ _mesa_reference_array_object(ctx, &obj, NULL);
+ }
+ }
+}
+
+
+/**
+ * Generate a set of unique array object IDs and store them in \c arrays.
+ * Helper for _mesa_GenVertexArrays[APPLE]() functions below.
+ * \param n Number of IDs to generate.
+ * \param arrays Array of \c n locations to store the IDs.
+ * \param vboOnly Will arrays have to reside in VBOs?
+ */
+static void
+gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays, GLboolean vboOnly)
+{
+ GLuint first;
+ GLint i;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenVertexArraysAPPLE");
+ return;
+ }
+
+ if (!arrays) {
+ return;
+ }
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Array.Objects, n);
+
+ /* Allocate new, empty array objects and return identifiers */
+ for (i = 0; i < n; i++) {
+ struct gl_array_object *obj;
+ GLuint name = first + i;
+
+ obj = (*ctx->Driver.NewArrayObject)( ctx, name );
+ if (!obj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE");
+ return;
+ }
+ obj->VBOonly = vboOnly;
+ save_array_object(ctx, obj);
+ arrays[i] = first + i;
+ }
+}
+
+
+/**
+ * ARB version of glGenVertexArrays()
+ * All arrays will be required to live in VBOs.
+ */
+void GLAPIENTRY
+_mesa_GenVertexArrays(GLsizei n, GLuint *arrays)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ gen_vertex_arrays(ctx, n, arrays, GL_TRUE);
+}
+
+
+/**
+ * APPLE version of glGenVertexArraysAPPLE()
+ * Arrays may live in VBOs or ordinary memory.
+ */
+void GLAPIENTRY
+_mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ gen_vertex_arrays(ctx, n, arrays, GL_FALSE);
+}
+
+
+/**
+ * Determine if ID is the name of an array object.
+ *
+ * \param id ID of the potential array object.
+ * \return \c GL_TRUE if \c id is the name of a array object,
+ * \c GL_FALSE otherwise.
+ */
+GLboolean GLAPIENTRY
+_mesa_IsVertexArrayAPPLE( GLuint id )
+{
+ struct gl_array_object * obj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ if (id == 0)
+ return GL_FALSE;
+
+ obj = lookup_arrayobj(ctx, id);
+
+ return (obj != NULL) ? GL_TRUE : GL_FALSE;
+}
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index a5e90d7cb..f2b8aa449 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -48,7 +48,7 @@
#include "program/program.h"
#include "program/prog_parameter.h"
#include "program/prog_uniform.h"
-#include "talloc.h"
+#include "ralloc.h"
#include <stdbool.h>
#include "../glsl/glsl_parser_extras.h"
@@ -1137,9 +1137,9 @@ validate_program(struct gl_context *ctx, GLuint program)
if (!shProg->Validated) {
/* update info log */
if (shProg->InfoLog) {
- talloc_free(shProg->InfoLog);
+ ralloc_free(shProg->InfoLog);
}
- shProg->InfoLog = talloc_strdup(shProg, errMsg);
+ shProg->InfoLog = ralloc_strdup(shProg, errMsg);
}
}
@@ -1855,7 +1855,7 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
#endif
}
- shProg->InfoLog = talloc_strdup_append(shProg->InfoLog, sh->InfoLog);
+ ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
}
delete_shader(ctx, shader);
diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c
index efee05ac6..1d7584559 100644
--- a/mesalib/src/mesa/main/shaderobj.c
+++ b/mesalib/src/mesa/main/shaderobj.c
@@ -1,413 +1,413 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
- * Copyright (C) 2009-2010 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 shaderobj.c
- * \author Brian Paul
- *
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/hash.h"
-#include "main/mfeatures.h"
-#include "main/mtypes.h"
-#include "main/shaderobj.h"
-#include "program/program.h"
-#include "program/prog_parameter.h"
-#include "program/prog_uniform.h"
-#include "talloc.h"
-
-/**********************************************************************/
-/*** Shader object functions ***/
-/**********************************************************************/
-
-
-/**
- * Set ptr to point to sh.
- * If ptr is pointing to another shader, decrement its refcount (and delete
- * if refcount hits zero).
- * Then set ptr to point to sh, incrementing its refcount.
- */
-void
-_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
- struct gl_shader *sh)
-{
- assert(ptr);
- if (*ptr == sh) {
- /* no-op */
- return;
- }
- if (*ptr) {
- /* Unreference the old shader */
- GLboolean deleteFlag = GL_FALSE;
- struct gl_shader *old = *ptr;
-
- ASSERT(old->RefCount > 0);
- old->RefCount--;
- /*printf("SHADER DECR %p (%d) to %d\n",
- (void*) old, old->Name, old->RefCount);*/
- deleteFlag = (old->RefCount == 0);
-
- if (deleteFlag) {
- _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
- ctx->Driver.DeleteShader(ctx, old);
- }
-
- *ptr = NULL;
- }
- assert(!*ptr);
-
- if (sh) {
- /* reference new */
- sh->RefCount++;
- /*printf("SHADER INCR %p (%d) to %d\n",
- (void*) sh, sh->Name, sh->RefCount);*/
- *ptr = sh;
- }
-}
-
-void
-_mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader)
-{
- shader->RefCount = 1;
-}
-
-/**
- * Allocate a new gl_shader object, initialize it.
- * Called via ctx->Driver.NewShader()
- */
-struct gl_shader *
-_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
-{
- struct gl_shader *shader;
- assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER ||
- type == GL_GEOMETRY_SHADER_ARB);
- shader = talloc_zero(NULL, struct gl_shader);
- if (shader) {
- shader->Type = type;
- shader->Name = name;
- _mesa_init_shader(ctx, shader);
- }
- return shader;
-}
-
-
-/**
- * Delete a shader object.
- * Called via ctx->Driver.DeleteShader().
- */
-static void
-_mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
-{
- if (sh->Source)
- free((void *) sh->Source);
- _mesa_reference_program(ctx, &sh->Program, NULL);
- talloc_free(sh);
-}
-
-
-/**
- * Lookup a GLSL shader object.
- */
-struct gl_shader *
-_mesa_lookup_shader(struct gl_context *ctx, GLuint name)
-{
- if (name) {
- struct gl_shader *sh = (struct gl_shader *)
- _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
- /* Note that both gl_shader and gl_shader_program objects are kept
- * in the same hash table. Check the object's type to be sure it's
- * what we're expecting.
- */
- if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
- return NULL;
- }
- return sh;
- }
- return NULL;
-}
-
-
-/**
- * As above, but record an error if shader is not found.
- */
-struct gl_shader *
-_mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller)
-{
- if (!name) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
- return NULL;
- }
- else {
- struct gl_shader *sh = (struct gl_shader *)
- _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
- if (!sh) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
- return NULL;
- }
- if (sh->Type == GL_SHADER_PROGRAM_MESA) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
- return NULL;
- }
- return sh;
- }
-}
-
-
-
-/**********************************************************************/
-/*** Shader Program object functions ***/
-/**********************************************************************/
-
-
-/**
- * Set ptr to point to shProg.
- * If ptr is pointing to another object, decrement its refcount (and delete
- * if refcount hits zero).
- * Then set ptr to point to shProg, incrementing its refcount.
- */
-void
-_mesa_reference_shader_program(struct gl_context *ctx,
- struct gl_shader_program **ptr,
- struct gl_shader_program *shProg)
-{
- assert(ptr);
- if (*ptr == shProg) {
- /* no-op */
- return;
- }
- if (*ptr) {
- /* Unreference the old shader program */
- GLboolean deleteFlag = GL_FALSE;
- struct gl_shader_program *old = *ptr;
-
- ASSERT(old->RefCount > 0);
- old->RefCount--;
-#if 0
- printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
- (void *) old, old->Name, old->RefCount);
-#endif
- deleteFlag = (old->RefCount == 0);
-
- if (deleteFlag) {
- _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
- ctx->Driver.DeleteShaderProgram(ctx, old);
- }
-
- *ptr = NULL;
- }
- assert(!*ptr);
-
- if (shProg) {
- shProg->RefCount++;
-#if 0
- printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
- (void *) shProg, shProg->Name, shProg->RefCount);
-#endif
- *ptr = shProg;
- }
-}
-
-void
-_mesa_init_shader_program(struct gl_context *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.
- * Called via ctx->Driver.NewShaderProgram()
- */
-static struct gl_shader_program *
-_mesa_new_shader_program(struct gl_context *ctx, GLuint name)
-{
- struct gl_shader_program *shProg;
- shProg = talloc_zero(NULL, struct gl_shader_program);
- if (shProg) {
- shProg->Name = name;
- _mesa_init_shader_program(ctx, shProg);
- }
- return shProg;
-}
-
-
-/**
- * Clear (free) the shader program state that gets produced by linking.
- */
-void
-_mesa_clear_shader_program_data(struct gl_context *ctx,
- struct gl_shader_program *shProg)
-{
- _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
- _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
- _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL);
-
- if (shProg->Uniforms) {
- _mesa_free_uniform_list(shProg->Uniforms);
- shProg->Uniforms = NULL;
- }
-
- if (shProg->Varying) {
- _mesa_free_parameter_list(shProg->Varying);
- shProg->Varying = NULL;
- }
-}
-
-
-/**
- * Free all the data that hangs off a shader program object, but not the
- * object itself.
- */
-void
-_mesa_free_shader_program_data(struct gl_context *ctx,
- struct gl_shader_program *shProg)
-{
- GLuint i;
- gl_shader_type sh;
-
- assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
-
- _mesa_clear_shader_program_data(ctx, shProg);
-
- if (shProg->Attributes) {
- _mesa_free_parameter_list(shProg->Attributes);
- shProg->Attributes = NULL;
- }
-
- /* detach shaders */
- for (i = 0; i < shProg->NumShaders; i++) {
- _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
- }
- shProg->NumShaders = 0;
-
- if (shProg->Shaders) {
- free(shProg->Shaders);
- shProg->Shaders = NULL;
- }
-
- if (shProg->InfoLog) {
- talloc_free(shProg->InfoLog);
- shProg->InfoLog = NULL;
- }
-
- /* Transform feedback varying vars */
- for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
- free(shProg->TransformFeedback.VaryingNames[i]);
- }
- free(shProg->TransformFeedback.VaryingNames);
- shProg->TransformFeedback.VaryingNames = NULL;
- shProg->TransformFeedback.NumVarying = 0;
-
-
- for (sh = 0; sh < MESA_SHADER_TYPES; sh++) {
- if (shProg->_LinkedShaders[sh] != NULL) {
- ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]);
- shProg->_LinkedShaders[sh] = NULL;
- }
- }
-}
-
-
-/**
- * Free/delete a shader program object.
- * Called via ctx->Driver.DeleteShaderProgram().
- */
-static void
-_mesa_delete_shader_program(struct gl_context *ctx, struct gl_shader_program *shProg)
-{
- _mesa_free_shader_program_data(ctx, shProg);
-
- talloc_free(shProg);
-}
-
-
-/**
- * Lookup a GLSL program object.
- */
-struct gl_shader_program *
-_mesa_lookup_shader_program(struct gl_context *ctx, GLuint name)
-{
- struct gl_shader_program *shProg;
- if (name) {
- shProg = (struct gl_shader_program *)
- _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
- /* Note that both gl_shader and gl_shader_program objects are kept
- * in the same hash table. Check the object's type to be sure it's
- * what we're expecting.
- */
- if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
- return NULL;
- }
- return shProg;
- }
- return NULL;
-}
-
-
-/**
- * As above, but record an error if program is not found.
- */
-struct gl_shader_program *
-_mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name,
- const char *caller)
-{
- if (!name) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
- return NULL;
- }
- else {
- struct gl_shader_program *shProg = (struct gl_shader_program *)
- _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
- if (!shProg) {
- _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
- return NULL;
- }
- if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
- return NULL;
- }
- return shProg;
- }
-}
-
-
-void
-_mesa_init_shader_object_functions(struct dd_function_table *driver)
-{
- driver->NewShader = _mesa_new_shader;
- driver->DeleteShader = _mesa_delete_shader;
- driver->NewShaderProgram = _mesa_new_shader_program;
- driver->DeleteShaderProgram = _mesa_delete_shader_program;
- driver->CompileShader = _mesa_ir_compile_shader;
- driver->LinkShader = _mesa_ir_link_shader;
-}
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009-2010 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 shaderobj.c
+ * \author Brian Paul
+ *
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "main/mfeatures.h"
+#include "main/mtypes.h"
+#include "main/shaderobj.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_uniform.h"
+#include "ralloc.h"
+
+/**********************************************************************/
+/*** Shader object functions ***/
+/**********************************************************************/
+
+
+/**
+ * Set ptr to point to sh.
+ * If ptr is pointing to another shader, decrement its refcount (and delete
+ * if refcount hits zero).
+ * Then set ptr to point to sh, incrementing its refcount.
+ */
+void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+ struct gl_shader *sh)
+{
+ assert(ptr);
+ if (*ptr == sh) {
+ /* no-op */
+ return;
+ }
+ if (*ptr) {
+ /* Unreference the old shader */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_shader *old = *ptr;
+
+ ASSERT(old->RefCount > 0);
+ old->RefCount--;
+ /*printf("SHADER DECR %p (%d) to %d\n",
+ (void*) old, old->Name, old->RefCount);*/
+ deleteFlag = (old->RefCount == 0);
+
+ if (deleteFlag) {
+ _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
+ ctx->Driver.DeleteShader(ctx, old);
+ }
+
+ *ptr = NULL;
+ }
+ assert(!*ptr);
+
+ if (sh) {
+ /* reference new */
+ sh->RefCount++;
+ /*printf("SHADER INCR %p (%d) to %d\n",
+ (void*) sh, sh->Name, sh->RefCount);*/
+ *ptr = sh;
+ }
+}
+
+void
+_mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader)
+{
+ shader->RefCount = 1;
+}
+
+/**
+ * Allocate a new gl_shader object, initialize it.
+ * Called via ctx->Driver.NewShader()
+ */
+struct gl_shader *
+_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
+{
+ struct gl_shader *shader;
+ assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER ||
+ type == GL_GEOMETRY_SHADER_ARB);
+ shader = rzalloc(NULL, struct gl_shader);
+ if (shader) {
+ shader->Type = type;
+ shader->Name = name;
+ _mesa_init_shader(ctx, shader);
+ }
+ return shader;
+}
+
+
+/**
+ * Delete a shader object.
+ * Called via ctx->Driver.DeleteShader().
+ */
+static void
+_mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
+{
+ if (sh->Source)
+ free((void *) sh->Source);
+ _mesa_reference_program(ctx, &sh->Program, NULL);
+ ralloc_free(sh);
+}
+
+
+/**
+ * Lookup a GLSL shader object.
+ */
+struct gl_shader *
+_mesa_lookup_shader(struct gl_context *ctx, GLuint name)
+{
+ if (name) {
+ struct gl_shader *sh = (struct gl_shader *)
+ _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+ /* Note that both gl_shader and gl_shader_program objects are kept
+ * in the same hash table. Check the object's type to be sure it's
+ * what we're expecting.
+ */
+ if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
+ return NULL;
+ }
+ return sh;
+ }
+ return NULL;
+}
+
+
+/**
+ * As above, but record an error if shader is not found.
+ */
+struct gl_shader *
+_mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller)
+{
+ if (!name) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
+ return NULL;
+ }
+ else {
+ struct gl_shader *sh = (struct gl_shader *)
+ _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+ if (!sh) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
+ return NULL;
+ }
+ if (sh->Type == GL_SHADER_PROGRAM_MESA) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
+ return NULL;
+ }
+ return sh;
+ }
+}
+
+
+
+/**********************************************************************/
+/*** Shader Program object functions ***/
+/**********************************************************************/
+
+
+/**
+ * Set ptr to point to shProg.
+ * If ptr is pointing to another object, decrement its refcount (and delete
+ * if refcount hits zero).
+ * Then set ptr to point to shProg, incrementing its refcount.
+ */
+void
+_mesa_reference_shader_program(struct gl_context *ctx,
+ struct gl_shader_program **ptr,
+ struct gl_shader_program *shProg)
+{
+ assert(ptr);
+ if (*ptr == shProg) {
+ /* no-op */
+ return;
+ }
+ if (*ptr) {
+ /* Unreference the old shader program */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_shader_program *old = *ptr;
+
+ ASSERT(old->RefCount > 0);
+ old->RefCount--;
+#if 0
+ printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
+ (void *) old, old->Name, old->RefCount);
+#endif
+ deleteFlag = (old->RefCount == 0);
+
+ if (deleteFlag) {
+ _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
+ ctx->Driver.DeleteShaderProgram(ctx, old);
+ }
+
+ *ptr = NULL;
+ }
+ assert(!*ptr);
+
+ if (shProg) {
+ shProg->RefCount++;
+#if 0
+ printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
+ (void *) shProg, shProg->Name, shProg->RefCount);
+#endif
+ *ptr = shProg;
+ }
+}
+
+void
+_mesa_init_shader_program(struct gl_context *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.
+ * Called via ctx->Driver.NewShaderProgram()
+ */
+static struct gl_shader_program *
+_mesa_new_shader_program(struct gl_context *ctx, GLuint name)
+{
+ struct gl_shader_program *shProg;
+ shProg = rzalloc(NULL, struct gl_shader_program);
+ if (shProg) {
+ shProg->Name = name;
+ _mesa_init_shader_program(ctx, shProg);
+ }
+ return shProg;
+}
+
+
+/**
+ * Clear (free) the shader program state that gets produced by linking.
+ */
+void
+_mesa_clear_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *shProg)
+{
+ _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
+ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
+ _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL);
+
+ if (shProg->Uniforms) {
+ _mesa_free_uniform_list(shProg->Uniforms);
+ shProg->Uniforms = NULL;
+ }
+
+ if (shProg->Varying) {
+ _mesa_free_parameter_list(shProg->Varying);
+ shProg->Varying = NULL;
+ }
+}
+
+
+/**
+ * Free all the data that hangs off a shader program object, but not the
+ * object itself.
+ */
+void
+_mesa_free_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *shProg)
+{
+ GLuint i;
+ gl_shader_type sh;
+
+ assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
+
+ _mesa_clear_shader_program_data(ctx, shProg);
+
+ if (shProg->Attributes) {
+ _mesa_free_parameter_list(shProg->Attributes);
+ shProg->Attributes = NULL;
+ }
+
+ /* detach shaders */
+ for (i = 0; i < shProg->NumShaders; i++) {
+ _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
+ }
+ shProg->NumShaders = 0;
+
+ if (shProg->Shaders) {
+ free(shProg->Shaders);
+ shProg->Shaders = NULL;
+ }
+
+ if (shProg->InfoLog) {
+ ralloc_free(shProg->InfoLog);
+ shProg->InfoLog = NULL;
+ }
+
+ /* Transform feedback varying vars */
+ for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
+ free(shProg->TransformFeedback.VaryingNames[i]);
+ }
+ free(shProg->TransformFeedback.VaryingNames);
+ shProg->TransformFeedback.VaryingNames = NULL;
+ shProg->TransformFeedback.NumVarying = 0;
+
+
+ for (sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ if (shProg->_LinkedShaders[sh] != NULL) {
+ ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]);
+ shProg->_LinkedShaders[sh] = NULL;
+ }
+ }
+}
+
+
+/**
+ * Free/delete a shader program object.
+ * Called via ctx->Driver.DeleteShaderProgram().
+ */
+static void
+_mesa_delete_shader_program(struct gl_context *ctx, struct gl_shader_program *shProg)
+{
+ _mesa_free_shader_program_data(ctx, shProg);
+
+ ralloc_free(shProg);
+}
+
+
+/**
+ * Lookup a GLSL program object.
+ */
+struct gl_shader_program *
+_mesa_lookup_shader_program(struct gl_context *ctx, GLuint name)
+{
+ struct gl_shader_program *shProg;
+ if (name) {
+ shProg = (struct gl_shader_program *)
+ _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+ /* Note that both gl_shader and gl_shader_program objects are kept
+ * in the same hash table. Check the object's type to be sure it's
+ * what we're expecting.
+ */
+ if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
+ return NULL;
+ }
+ return shProg;
+ }
+ return NULL;
+}
+
+
+/**
+ * As above, but record an error if program is not found.
+ */
+struct gl_shader_program *
+_mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name,
+ const char *caller)
+{
+ if (!name) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
+ return NULL;
+ }
+ else {
+ struct gl_shader_program *shProg = (struct gl_shader_program *)
+ _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+ if (!shProg) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
+ return NULL;
+ }
+ if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
+ return NULL;
+ }
+ return shProg;
+ }
+}
+
+
+void
+_mesa_init_shader_object_functions(struct dd_function_table *driver)
+{
+ driver->NewShader = _mesa_new_shader;
+ driver->DeleteShader = _mesa_delete_shader;
+ driver->NewShaderProgram = _mesa_new_shader_program;
+ driver->DeleteShaderProgram = _mesa_delete_shader_program;
+ driver->CompileShader = _mesa_ir_compile_shader;
+ driver->LinkShader = _mesa_ir_link_shader;
+}
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 404b6c646..3794c0de0 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -105,13 +105,13 @@ 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). */
+ /* Callers of this ralloc-based new need not call delete. It's
+ * easier to just ralloc_free 'ctx' (or any of its ancestors). */
static void* operator new(size_t size, void *ctx)
{
void *node;
- node = talloc_zero_size(ctx, size);
+ node = rzalloc_size(ctx, size);
assert(node != NULL);
return node;
@@ -318,7 +318,7 @@ 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);
+ ralloc_vasprintf_append(&prog->InfoLog, fmt, args);
va_end(args);
prog->LinkStatus = GL_FALSE;
@@ -1570,7 +1570,7 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)
this->result, src_reg_for_float(element_size));
}
- src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
+ src_reg.reladdr = ralloc(mem_ctx, ir_to_mesa_src_reg);
memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
}
@@ -1927,7 +1927,7 @@ ir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
return entry;
}
- entry = talloc(mem_ctx, function_entry);
+ entry = ralloc(mem_ctx, function_entry);
entry->sig = sig;
entry->sig_id = this->next_signature_id++;
entry->bgn_inst = NULL;
@@ -2264,12 +2264,12 @@ ir_to_mesa_visitor::ir_to_mesa_visitor()
next_temp = 1;
next_signature_id = 1;
current_function = NULL;
- mem_ctx = talloc_new(NULL);
+ mem_ctx = ralloc_context(NULL);
}
ir_to_mesa_visitor::~ir_to_mesa_visitor()
{
- talloc_free(mem_ctx);
+ ralloc_free(mem_ctx);
}
static struct prog_src_register
@@ -2318,8 +2318,8 @@ set_branchtargets(ir_to_mesa_visitor *v,
}
}
- if_stack = talloc_zero_array(v->mem_ctx, int, if_count);
- loop_stack = talloc_zero_array(v->mem_ctx, int, loop_count);
+ if_stack = rzalloc_array(v->mem_ctx, int, if_count);
+ loop_stack = rzalloc_array(v->mem_ctx, int, loop_count);
for (i = 0; i < num_instructions; i++) {
switch (mesa_instructions[i].Opcode) {
@@ -2462,7 +2462,7 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
unsigned int next_sampler = 0, num_uniforms = 0;
struct uniform_sort *sorted_uniforms;
- sorted_uniforms = talloc_array(NULL, struct uniform_sort,
+ sorted_uniforms = ralloc_array(NULL, struct uniform_sort,
shader_program->Uniforms->NumUniforms);
for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) {
@@ -2541,7 +2541,7 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
}
}
- talloc_free(sorted_uniforms);
+ ralloc_free(sorted_uniforms);
}
static void
@@ -2557,7 +2557,7 @@ set_uniform_initializer(struct gl_context *ctx, void *mem_ctx,
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,
+ const char *field_name = ralloc_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);
@@ -2588,7 +2588,7 @@ set_uniform_initializer(struct gl_context *ctx, void *mem_ctx,
void *values;
if (element_type->base_type == GLSL_TYPE_BOOL) {
- int *conv = talloc_array(mem_ctx, int, element_type->components());
+ int *conv = ralloc_array(mem_ctx, int, element_type->components());
for (unsigned int j = 0; j < element_type->components(); j++) {
conv[j] = element->value.b[j];
}
@@ -2634,14 +2634,14 @@ set_uniform_initializers(struct gl_context *ctx,
continue;
if (!mem_ctx)
- mem_ctx = talloc_new(NULL);
+ mem_ctx = ralloc_context(NULL);
set_uniform_initializer(ctx, mem_ctx, shader_program, var->name,
var->type, var->constant_value);
}
}
- talloc_free(mem_ctx);
+ ralloc_free(mem_ctx);
}
/*
@@ -2667,7 +2667,7 @@ set_uniform_initializers(struct gl_context *ctx,
void
ir_to_mesa_visitor::copy_propagate(void)
{
- ir_to_mesa_instruction **acp = talloc_zero_array(mem_ctx,
+ ir_to_mesa_instruction **acp = rzalloc_array(mem_ctx,
ir_to_mesa_instruction *,
this->next_temp * 4);
@@ -2771,7 +2771,7 @@ ir_to_mesa_visitor::copy_propagate(void)
}
}
- talloc_free(acp);
+ ralloc_free(acp);
}
@@ -2870,7 +2870,7 @@ get_mesa_program(struct gl_context *ctx,
mesa_instructions =
(struct prog_instruction *)calloc(num_instructions,
sizeof(*mesa_instructions));
- mesa_instruction_annotation = talloc_array(v.mem_ctx, ir_instruction *,
+ mesa_instruction_annotation = ralloc_array(v.mem_ctx, ir_instruction *,
num_instructions);
v.copy_propagate();
@@ -3127,7 +3127,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
_mesa_glsl_lexer_dtor(state);
}
- talloc_free(shader->ir);
+ ralloc_free(shader->ir);
shader->ir = new(shader) exec_list;
if (!state->error && !state->translation_unit.is_empty())
_mesa_ast_to_hir(shader->ir, state);
@@ -3174,7 +3174,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader)
/* Retain any live IR, but trash the rest. */
reparent_ir(shader->ir, shader->ir);
- talloc_free(state);
+ ralloc_free(state);
if (shader->CompileStatus) {
if (!ctx->Driver.CompileShader(ctx, shader))
diff --git a/mesalib/src/mesa/program/register_allocate.c b/mesalib/src/mesa/program/register_allocate.c
index 8992b91b6..95a9bde40 100644
--- a/mesalib/src/mesa/program/register_allocate.c
+++ b/mesalib/src/mesa/program/register_allocate.c
@@ -1,458 +1,455 @@
-/*
- * 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 <eric@anholt.net>
- *
- */
-
-/** @file register_allocate.c
- *
- * Graph-coloring register allocator.
- */
-
-#include <talloc.h>
-
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-#include "register_allocate.h"
-
-struct ra_reg {
- GLboolean *conflicts;
- unsigned int *conflict_list;
- unsigned int conflict_list_size;
- unsigned int num_conflicts;
-};
-
-struct ra_regs {
- struct ra_reg *regs;
- unsigned int count;
-
- struct ra_class **classes;
- unsigned int class_count;
-};
-
-struct ra_class {
- GLboolean *regs;
-
- /**
- * p_B in Runeson/Nyström paper.
- *
- * This is "how many regs are in the set."
- */
- unsigned int p;
-
- /**
- * q_B,C in Runeson/Nyström paper.
- */
- unsigned int *q;
-};
-
-struct ra_node {
- GLboolean *adjacency;
- unsigned int *adjacency_list;
- unsigned int class;
- unsigned int adjacency_count;
- unsigned int reg;
- GLboolean in_stack;
- float spill_cost;
-};
-
-struct ra_graph {
- struct ra_regs *regs;
- /**
- * the variables that need register allocation.
- */
- struct ra_node *nodes;
- unsigned int count; /**< count of nodes. */
-
- unsigned int *stack;
- unsigned int stack_count;
-};
-
-struct ra_regs *
-ra_alloc_reg_set(unsigned int count)
-{
- unsigned int i;
- struct ra_regs *regs;
-
- regs = talloc_zero(NULL, struct ra_regs);
- regs->count = count;
- regs->regs = talloc_zero_array(regs, struct ra_reg, count);
-
- for (i = 0; i < count; i++) {
- regs->regs[i].conflicts = talloc_zero_array(regs->regs, GLboolean, count);
- regs->regs[i].conflicts[i] = GL_TRUE;
-
- regs->regs[i].conflict_list = talloc_array(regs->regs, unsigned int, 4);
- regs->regs[i].conflict_list_size = 4;
- regs->regs[i].conflict_list[0] = i;
- regs->regs[i].num_conflicts = 1;
- }
-
- return regs;
-}
-
-static void
-ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2)
-{
- struct ra_reg *reg1 = &regs->regs[r1];
-
- if (reg1->conflict_list_size == reg1->num_conflicts) {
- reg1->conflict_list_size *= 2;
- reg1->conflict_list = talloc_realloc(regs->regs,
- reg1->conflict_list,
- unsigned int,
- reg1->conflict_list_size);
- }
- reg1->conflict_list[reg1->num_conflicts++] = r2;
- reg1->conflicts[r2] = GL_TRUE;
-}
-
-void
-ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2)
-{
- if (!regs->regs[r1].conflicts[r2]) {
- ra_add_conflict_list(regs, r1, r2);
- ra_add_conflict_list(regs, r2, r1);
- }
-}
-
-unsigned int
-ra_alloc_reg_class(struct ra_regs *regs)
-{
- struct ra_class *class;
-
- regs->classes = talloc_realloc(regs->regs, regs->classes,
- struct ra_class *,
- regs->class_count + 1);
-
- class = talloc_zero(regs, struct ra_class);
- regs->classes[regs->class_count] = class;
-
- class->regs = talloc_zero_array(class, GLboolean, regs->count);
-
- return regs->class_count++;
-}
-
-void
-ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int r)
-{
- struct ra_class *class = regs->classes[c];
-
- class->regs[r] = GL_TRUE;
- class->p++;
-}
-
-/**
- * Must be called after all conflicts and register classes have been
- * set up and before the register set is used for allocation.
- */
-void
-ra_set_finalize(struct ra_regs *regs)
-{
- unsigned int b, c;
-
- for (b = 0; b < regs->class_count; b++) {
- regs->classes[b]->q = talloc_array(regs, unsigned int, regs->class_count);
- }
-
- /* Compute, for each class B and C, how many regs of B an
- * allocation to C could conflict with.
- */
- for (b = 0; b < regs->class_count; b++) {
- for (c = 0; c < regs->class_count; c++) {
- unsigned int rc;
- int max_conflicts = 0;
-
- for (rc = 0; rc < regs->count; rc++) {
- int conflicts = 0;
- int i;
-
- if (!regs->classes[c]->regs[rc])
- continue;
-
- for (i = 0; i < regs->regs[rc].num_conflicts; i++) {
- unsigned int rb = regs->regs[rc].conflict_list[i];
- if (regs->classes[b]->regs[rb])
- conflicts++;
- }
- max_conflicts = MAX2(max_conflicts, conflicts);
- }
- regs->classes[b]->q[c] = max_conflicts;
- }
- }
-}
-
-static void
-ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2)
-{
- g->nodes[n1].adjacency[n2] = GL_TRUE;
- g->nodes[n1].adjacency_list[g->nodes[n1].adjacency_count] = n2;
- g->nodes[n1].adjacency_count++;
-}
-
-struct ra_graph *
-ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count)
-{
- struct ra_graph *g;
- unsigned int i;
-
- g = talloc_zero(regs, struct ra_graph);
- g->regs = regs;
- g->nodes = talloc_zero_array(g, struct ra_node, count);
- g->count = count;
-
- g->stack = talloc_zero_array(g, unsigned int, count);
-
- for (i = 0; i < count; i++) {
- g->nodes[i].adjacency = talloc_zero_array(g, GLboolean, count);
- g->nodes[i].adjacency_list = talloc_array(g, unsigned int, count);
- g->nodes[i].adjacency_count = 0;
- ra_add_node_adjacency(g, i, i);
- g->nodes[i].reg = ~0;
- }
-
- return g;
-}
-
-void
-ra_set_node_class(struct ra_graph *g,
- unsigned int n, unsigned int class)
-{
- g->nodes[n].class = class;
-}
-
-void
-ra_add_node_interference(struct ra_graph *g,
- unsigned int n1, unsigned int n2)
-{
- if (!g->nodes[n1].adjacency[n2]) {
- ra_add_node_adjacency(g, n1, n2);
- ra_add_node_adjacency(g, n2, n1);
- }
-}
-
-static GLboolean pq_test(struct ra_graph *g, unsigned int n)
-{
- unsigned int j;
- unsigned int q = 0;
- int n_class = g->nodes[n].class;
-
- for (j = 0; j < g->nodes[n].adjacency_count; j++) {
- unsigned int n2 = g->nodes[n].adjacency_list[j];
- unsigned int n2_class = g->nodes[n2].class;
-
- if (n != n2 && !g->nodes[n2].in_stack) {
- q += g->regs->classes[n_class]->q[n2_class];
- }
- }
-
- return q < g->regs->classes[n_class]->p;
-}
-
-/**
- * Simplifies the interference graph by pushing all
- * trivially-colorable nodes into a stack of nodes to be colored,
- * removing them from the graph, and rinsing and repeating.
- *
- * Returns GL_TRUE if all nodes were removed from the graph. GL_FALSE
- * means that either spilling will be required, or optimistic coloring
- * should be applied.
- */
-GLboolean
-ra_simplify(struct ra_graph *g)
-{
- GLboolean progress = GL_TRUE;
- int i;
-
- while (progress) {
- progress = GL_FALSE;
-
- for (i = g->count - 1; i >= 0; i--) {
- if (g->nodes[i].in_stack)
- continue;
-
- if (pq_test(g, i)) {
- g->stack[g->stack_count] = i;
- g->stack_count++;
- g->nodes[i].in_stack = GL_TRUE;
- progress = GL_TRUE;
- }
- }
- }
-
- for (i = 0; i < g->count; i++) {
- if (!g->nodes[i].in_stack)
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-/**
- * Pops nodes from the stack back into the graph, coloring them with
- * registers as they go.
- *
- * If all nodes were trivially colorable, then this must succeed. If
- * not (optimistic coloring), then it may return GL_FALSE;
- */
-GLboolean
-ra_select(struct ra_graph *g)
-{
- int i;
-
- while (g->stack_count != 0) {
- unsigned int r;
- int n = g->stack[g->stack_count - 1];
- struct ra_class *c = g->regs->classes[g->nodes[n].class];
-
- /* Find the lowest-numbered reg which is not used by a member
- * of the graph adjacent to us.
- */
- for (r = 0; r < g->regs->count; r++) {
- if (!c->regs[r])
- continue;
-
- /* Check if any of our neighbors conflict with this register choice. */
- for (i = 0; i < g->nodes[n].adjacency_count; i++) {
- unsigned int n2 = g->nodes[n].adjacency_list[i];
-
- if (!g->nodes[n2].in_stack &&
- g->regs->regs[r].conflicts[g->nodes[n2].reg]) {
- break;
- }
- }
- if (i == g->nodes[n].adjacency_count)
- break;
- }
- if (r == g->regs->count)
- return GL_FALSE;
-
- g->nodes[n].reg = r;
- g->nodes[n].in_stack = GL_FALSE;
- g->stack_count--;
- }
-
- return GL_TRUE;
-}
-
-/**
- * Optimistic register coloring: Just push the remaining nodes
- * on the stack. They'll be colored first in ra_select(), and
- * if they succeed then the locally-colorable nodes are still
- * locally-colorable and the rest of the register allocation
- * will succeed.
- */
-void
-ra_optimistic_color(struct ra_graph *g)
-{
- unsigned int i;
-
- for (i = 0; i < g->count; i++) {
- if (g->nodes[i].in_stack)
- continue;
-
- g->stack[g->stack_count] = i;
- g->stack_count++;
- g->nodes[i].in_stack = GL_TRUE;
- }
-}
-
-GLboolean
-ra_allocate_no_spills(struct ra_graph *g)
-{
- if (!ra_simplify(g)) {
- ra_optimistic_color(g);
- }
- return ra_select(g);
-}
-
-unsigned int
-ra_get_node_reg(struct ra_graph *g, unsigned int n)
-{
- return g->nodes[n].reg;
-}
-
-static float
-ra_get_spill_benefit(struct ra_graph *g, unsigned int n)
-{
- int j;
- float benefit = 0;
- int n_class = g->nodes[n].class;
-
- /* Define the benefit of eliminating an interference between n, n2
- * through spilling as q(C, B) / p(C). This is similar to the
- * "count number of edges" approach of traditional graph coloring,
- * but takes classes into account.
- */
- for (j = 0; j < g->nodes[n].adjacency_count; j++) {
- unsigned int n2 = g->nodes[n].adjacency_list[j];
- if (n != n2) {
- unsigned int n2_class = g->nodes[n2].class;
- benefit += ((float)g->regs->classes[n_class]->q[n2_class] /
- g->regs->classes[n_class]->p);
- }
- }
-
- return benefit;
-}
-
-/**
- * Returns a node number to be spilled according to the cost/benefit using
- * the pq test, or -1 if there are no spillable nodes.
- */
-int
-ra_get_best_spill_node(struct ra_graph *g)
-{
- unsigned int best_node = -1;
- unsigned int best_benefit = 0.0;
- unsigned int n;
-
- for (n = 0; n < g->count; n++) {
- float cost = g->nodes[n].spill_cost;
- float benefit;
-
- if (cost <= 0.0)
- continue;
-
- benefit = ra_get_spill_benefit(g, n);
-
- if (benefit / cost > best_benefit) {
- best_benefit = benefit / cost;
- best_node = n;
- }
- }
-
- return best_node;
-}
-
-/**
- * Only nodes with a spill cost set (cost != 0.0) will be considered
- * for register spilling.
- */
-void
-ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost)
-{
- g->nodes[n].spill_cost = cost;
-}
+/*
+ * 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 <eric@anholt.net>
+ *
+ */
+
+/** @file register_allocate.c
+ *
+ * Graph-coloring register allocator.
+ */
+
+#include <ralloc.h>
+
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "register_allocate.h"
+
+struct ra_reg {
+ GLboolean *conflicts;
+ unsigned int *conflict_list;
+ unsigned int conflict_list_size;
+ unsigned int num_conflicts;
+};
+
+struct ra_regs {
+ struct ra_reg *regs;
+ unsigned int count;
+
+ struct ra_class **classes;
+ unsigned int class_count;
+};
+
+struct ra_class {
+ GLboolean *regs;
+
+ /**
+ * p_B in Runeson/Nyström paper.
+ *
+ * This is "how many regs are in the set."
+ */
+ unsigned int p;
+
+ /**
+ * q_B,C in Runeson/Nyström paper.
+ */
+ unsigned int *q;
+};
+
+struct ra_node {
+ GLboolean *adjacency;
+ unsigned int *adjacency_list;
+ unsigned int class;
+ unsigned int adjacency_count;
+ unsigned int reg;
+ GLboolean in_stack;
+ float spill_cost;
+};
+
+struct ra_graph {
+ struct ra_regs *regs;
+ /**
+ * the variables that need register allocation.
+ */
+ struct ra_node *nodes;
+ unsigned int count; /**< count of nodes. */
+
+ unsigned int *stack;
+ unsigned int stack_count;
+};
+
+struct ra_regs *
+ra_alloc_reg_set(unsigned int count)
+{
+ unsigned int i;
+ struct ra_regs *regs;
+
+ regs = rzalloc(NULL, struct ra_regs);
+ regs->count = count;
+ regs->regs = rzalloc_array(regs, struct ra_reg, count);
+
+ for (i = 0; i < count; i++) {
+ regs->regs[i].conflicts = rzalloc_array(regs->regs, GLboolean, count);
+ regs->regs[i].conflicts[i] = GL_TRUE;
+
+ regs->regs[i].conflict_list = ralloc_array(regs->regs, unsigned int, 4);
+ regs->regs[i].conflict_list_size = 4;
+ regs->regs[i].conflict_list[0] = i;
+ regs->regs[i].num_conflicts = 1;
+ }
+
+ return regs;
+}
+
+static void
+ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2)
+{
+ struct ra_reg *reg1 = &regs->regs[r1];
+
+ if (reg1->conflict_list_size == reg1->num_conflicts) {
+ reg1->conflict_list_size *= 2;
+ reg1->conflict_list = reralloc(regs->regs, reg1->conflict_list,
+ unsigned int, reg1->conflict_list_size);
+ }
+ reg1->conflict_list[reg1->num_conflicts++] = r2;
+ reg1->conflicts[r2] = GL_TRUE;
+}
+
+void
+ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2)
+{
+ if (!regs->regs[r1].conflicts[r2]) {
+ ra_add_conflict_list(regs, r1, r2);
+ ra_add_conflict_list(regs, r2, r1);
+ }
+}
+
+unsigned int
+ra_alloc_reg_class(struct ra_regs *regs)
+{
+ struct ra_class *class;
+
+ regs->classes = reralloc(regs->regs, regs->classes, struct ra_class *,
+ regs->class_count + 1);
+
+ class = rzalloc(regs, struct ra_class);
+ regs->classes[regs->class_count] = class;
+
+ class->regs = rzalloc_array(class, GLboolean, regs->count);
+
+ return regs->class_count++;
+}
+
+void
+ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int r)
+{
+ struct ra_class *class = regs->classes[c];
+
+ class->regs[r] = GL_TRUE;
+ class->p++;
+}
+
+/**
+ * Must be called after all conflicts and register classes have been
+ * set up and before the register set is used for allocation.
+ */
+void
+ra_set_finalize(struct ra_regs *regs)
+{
+ unsigned int b, c;
+
+ for (b = 0; b < regs->class_count; b++) {
+ regs->classes[b]->q = ralloc_array(regs, unsigned int, regs->class_count);
+ }
+
+ /* Compute, for each class B and C, how many regs of B an
+ * allocation to C could conflict with.
+ */
+ for (b = 0; b < regs->class_count; b++) {
+ for (c = 0; c < regs->class_count; c++) {
+ unsigned int rc;
+ int max_conflicts = 0;
+
+ for (rc = 0; rc < regs->count; rc++) {
+ int conflicts = 0;
+ int i;
+
+ if (!regs->classes[c]->regs[rc])
+ continue;
+
+ for (i = 0; i < regs->regs[rc].num_conflicts; i++) {
+ unsigned int rb = regs->regs[rc].conflict_list[i];
+ if (regs->classes[b]->regs[rb])
+ conflicts++;
+ }
+ max_conflicts = MAX2(max_conflicts, conflicts);
+ }
+ regs->classes[b]->q[c] = max_conflicts;
+ }
+ }
+}
+
+static void
+ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2)
+{
+ g->nodes[n1].adjacency[n2] = GL_TRUE;
+ g->nodes[n1].adjacency_list[g->nodes[n1].adjacency_count] = n2;
+ g->nodes[n1].adjacency_count++;
+}
+
+struct ra_graph *
+ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count)
+{
+ struct ra_graph *g;
+ unsigned int i;
+
+ g = rzalloc(regs, struct ra_graph);
+ g->regs = regs;
+ g->nodes = rzalloc_array(g, struct ra_node, count);
+ g->count = count;
+
+ g->stack = rzalloc_array(g, unsigned int, count);
+
+ for (i = 0; i < count; i++) {
+ g->nodes[i].adjacency = rzalloc_array(g, GLboolean, count);
+ g->nodes[i].adjacency_list = ralloc_array(g, unsigned int, count);
+ g->nodes[i].adjacency_count = 0;
+ ra_add_node_adjacency(g, i, i);
+ g->nodes[i].reg = ~0;
+ }
+
+ return g;
+}
+
+void
+ra_set_node_class(struct ra_graph *g,
+ unsigned int n, unsigned int class)
+{
+ g->nodes[n].class = class;
+}
+
+void
+ra_add_node_interference(struct ra_graph *g,
+ unsigned int n1, unsigned int n2)
+{
+ if (!g->nodes[n1].adjacency[n2]) {
+ ra_add_node_adjacency(g, n1, n2);
+ ra_add_node_adjacency(g, n2, n1);
+ }
+}
+
+static GLboolean pq_test(struct ra_graph *g, unsigned int n)
+{
+ unsigned int j;
+ unsigned int q = 0;
+ int n_class = g->nodes[n].class;
+
+ for (j = 0; j < g->nodes[n].adjacency_count; j++) {
+ unsigned int n2 = g->nodes[n].adjacency_list[j];
+ unsigned int n2_class = g->nodes[n2].class;
+
+ if (n != n2 && !g->nodes[n2].in_stack) {
+ q += g->regs->classes[n_class]->q[n2_class];
+ }
+ }
+
+ return q < g->regs->classes[n_class]->p;
+}
+
+/**
+ * Simplifies the interference graph by pushing all
+ * trivially-colorable nodes into a stack of nodes to be colored,
+ * removing them from the graph, and rinsing and repeating.
+ *
+ * Returns GL_TRUE if all nodes were removed from the graph. GL_FALSE
+ * means that either spilling will be required, or optimistic coloring
+ * should be applied.
+ */
+GLboolean
+ra_simplify(struct ra_graph *g)
+{
+ GLboolean progress = GL_TRUE;
+ int i;
+
+ while (progress) {
+ progress = GL_FALSE;
+
+ for (i = g->count - 1; i >= 0; i--) {
+ if (g->nodes[i].in_stack)
+ continue;
+
+ if (pq_test(g, i)) {
+ g->stack[g->stack_count] = i;
+ g->stack_count++;
+ g->nodes[i].in_stack = GL_TRUE;
+ progress = GL_TRUE;
+ }
+ }
+ }
+
+ for (i = 0; i < g->count; i++) {
+ if (!g->nodes[i].in_stack)
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/**
+ * Pops nodes from the stack back into the graph, coloring them with
+ * registers as they go.
+ *
+ * If all nodes were trivially colorable, then this must succeed. If
+ * not (optimistic coloring), then it may return GL_FALSE;
+ */
+GLboolean
+ra_select(struct ra_graph *g)
+{
+ int i;
+
+ while (g->stack_count != 0) {
+ unsigned int r;
+ int n = g->stack[g->stack_count - 1];
+ struct ra_class *c = g->regs->classes[g->nodes[n].class];
+
+ /* Find the lowest-numbered reg which is not used by a member
+ * of the graph adjacent to us.
+ */
+ for (r = 0; r < g->regs->count; r++) {
+ if (!c->regs[r])
+ continue;
+
+ /* Check if any of our neighbors conflict with this register choice. */
+ for (i = 0; i < g->nodes[n].adjacency_count; i++) {
+ unsigned int n2 = g->nodes[n].adjacency_list[i];
+
+ if (!g->nodes[n2].in_stack &&
+ g->regs->regs[r].conflicts[g->nodes[n2].reg]) {
+ break;
+ }
+ }
+ if (i == g->nodes[n].adjacency_count)
+ break;
+ }
+ if (r == g->regs->count)
+ return GL_FALSE;
+
+ g->nodes[n].reg = r;
+ g->nodes[n].in_stack = GL_FALSE;
+ g->stack_count--;
+ }
+
+ return GL_TRUE;
+}
+
+/**
+ * Optimistic register coloring: Just push the remaining nodes
+ * on the stack. They'll be colored first in ra_select(), and
+ * if they succeed then the locally-colorable nodes are still
+ * locally-colorable and the rest of the register allocation
+ * will succeed.
+ */
+void
+ra_optimistic_color(struct ra_graph *g)
+{
+ unsigned int i;
+
+ for (i = 0; i < g->count; i++) {
+ if (g->nodes[i].in_stack)
+ continue;
+
+ g->stack[g->stack_count] = i;
+ g->stack_count++;
+ g->nodes[i].in_stack = GL_TRUE;
+ }
+}
+
+GLboolean
+ra_allocate_no_spills(struct ra_graph *g)
+{
+ if (!ra_simplify(g)) {
+ ra_optimistic_color(g);
+ }
+ return ra_select(g);
+}
+
+unsigned int
+ra_get_node_reg(struct ra_graph *g, unsigned int n)
+{
+ return g->nodes[n].reg;
+}
+
+static float
+ra_get_spill_benefit(struct ra_graph *g, unsigned int n)
+{
+ int j;
+ float benefit = 0;
+ int n_class = g->nodes[n].class;
+
+ /* Define the benefit of eliminating an interference between n, n2
+ * through spilling as q(C, B) / p(C). This is similar to the
+ * "count number of edges" approach of traditional graph coloring,
+ * but takes classes into account.
+ */
+ for (j = 0; j < g->nodes[n].adjacency_count; j++) {
+ unsigned int n2 = g->nodes[n].adjacency_list[j];
+ if (n != n2) {
+ unsigned int n2_class = g->nodes[n2].class;
+ benefit += ((float)g->regs->classes[n_class]->q[n2_class] /
+ g->regs->classes[n_class]->p);
+ }
+ }
+
+ return benefit;
+}
+
+/**
+ * Returns a node number to be spilled according to the cost/benefit using
+ * the pq test, or -1 if there are no spillable nodes.
+ */
+int
+ra_get_best_spill_node(struct ra_graph *g)
+{
+ unsigned int best_node = -1;
+ unsigned int best_benefit = 0.0;
+ unsigned int n;
+
+ for (n = 0; n < g->count; n++) {
+ float cost = g->nodes[n].spill_cost;
+ float benefit;
+
+ if (cost <= 0.0)
+ continue;
+
+ benefit = ra_get_spill_benefit(g, n);
+
+ if (benefit / cost > best_benefit) {
+ best_benefit = benefit / cost;
+ best_node = n;
+ }
+ }
+
+ return best_node;
+}
+
+/**
+ * Only nodes with a spill cost set (cost != 0.0) will be considered
+ * for register spilling.
+ */
+void
+ra_set_node_spill_cost(struct ra_graph *g, unsigned int n, float cost)
+{
+ g->nodes[n].spill_cost = cost;
+}
diff --git a/mesalib/src/mesa/program/sampler.cpp b/mesalib/src/mesa/program/sampler.cpp
index cd44467a3..12c4a40a2 100644
--- a/mesalib/src/mesa/program/sampler.cpp
+++ b/mesalib/src/mesa/program/sampler.cpp
@@ -1,140 +1,138 @@
-/*
- * 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.
- */
-
-#include <cstdio>
-#include "ir.h"
-#include "glsl_types.h"
-#include "ir_visitor.h"
-
-extern "C" {
-#include "main/compiler.h"
-#include "main/mtypes.h"
-#include "program/prog_parameter.h"
-}
-
-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;
-}
-
-class get_sampler_name : public ir_hierarchical_visitor
-{
-public:
- get_sampler_name(ir_dereference *last,
- struct gl_shader_program *shader_program)
- {
- this->mem_ctx = talloc_new(NULL);
- this->shader_program = shader_program;
- this->name = NULL;
- this->offset = 0;
- this->last = last;
- }
-
- ~get_sampler_name()
- {
- talloc_free(this->mem_ctx);
- }
-
- 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.
- */
- shader_program->InfoLog =
- talloc_asprintf_append(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;
- }
-
- struct gl_shader_program *shader_program;
- const char *name;
- void *mem_ctx;
- int offset;
- ir_dereference *last;
-};
-
-extern "C" {
-int
-_mesa_get_sampler_uniform_value(class ir_dereference *sampler,
- struct gl_shader_program *shader_program,
- const struct gl_program *prog)
-{
- get_sampler_name getname(sampler, shader_program);
-
- sampler->accept(&getname);
-
- GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
- getname.name);
-
- if (index < 0) {
- fail_link(shader_program,
- "failed to find sampler named %s.\n", getname.name);
- return 0;
- }
-
- index += getname.offset;
-
- return prog->Parameters->ParameterValues[index][0];
-}
-}
+/*
+ * 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.
+ */
+
+#include <cstdio>
+#include "ir.h"
+#include "glsl_types.h"
+#include "ir_visitor.h"
+
+extern "C" {
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "program/prog_parameter.h"
+}
+
+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);
+ ralloc_vasprintf_append(&prog->InfoLog, fmt, args);
+ va_end(args);
+
+ prog->LinkStatus = GL_FALSE;
+}
+
+class get_sampler_name : public ir_hierarchical_visitor
+{
+public:
+ get_sampler_name(ir_dereference *last,
+ struct gl_shader_program *shader_program)
+ {
+ this->mem_ctx = ralloc_context(NULL);
+ this->shader_program = shader_program;
+ this->name = NULL;
+ this->offset = 0;
+ this->last = last;
+ }
+
+ ~get_sampler_name()
+ {
+ ralloc_free(this->mem_ctx);
+ }
+
+ 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 = ralloc_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.
+ */
+ ralloc_strcat(&shader_program->InfoLog,
+ "warning: Variable sampler array index unsupported.\n"
+ "This 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 = ralloc_asprintf(mem_ctx, "%s[%d]", name, i);
+ } else {
+ offset = i;
+ }
+ return visit_continue;
+ }
+
+ struct gl_shader_program *shader_program;
+ const char *name;
+ void *mem_ctx;
+ int offset;
+ ir_dereference *last;
+};
+
+extern "C" {
+int
+_mesa_get_sampler_uniform_value(class ir_dereference *sampler,
+ struct gl_shader_program *shader_program,
+ const struct gl_program *prog)
+{
+ get_sampler_name getname(sampler, shader_program);
+
+ sampler->accept(&getname);
+
+ GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
+ getname.name);
+
+ if (index < 0) {
+ fail_link(shader_program,
+ "failed to find sampler named %s.\n", getname.name);
+ return 0;
+ }
+
+ index += getname.offset;
+
+ return prog->Parameters->ParameterValues[index][0];
+}
+}