From bfd5916eafb9a97ad10f1d4a8738e7dcb02e04f4 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 14:25:04 +0900 Subject: Code reorganization: split gallium and mesa makefiles. In other words, don't build src/gallium source code from within src/mesa/Makefile. Also, allow to customize which gallium auxiliary dirs, driver driver, winsys dirs get built from the config/* files. --- src/gallium/Makefile.template | 1 + src/gallium/auxiliary/Makefile | 6 +- src/gallium/auxiliary/cso_cache/Makefile | 18 +++++ src/gallium/auxiliary/draw/Makefile | 41 ++++++++++- src/gallium/auxiliary/tgsi/Makefile | 24 ++++++- src/gallium/auxiliary/tgsi/exec/Makefile | 3 - src/gallium/auxiliary/util/Makefile | 20 ++++++ src/gallium/drivers/Makefile | 6 +- src/gallium/winsys/Makefile | 20 ++++++ src/gallium/winsys/dri/Makefile.template | 6 +- src/gallium/winsys/xlib/Makefile | 113 +++++++++++++++++++++++++++++++ src/mesa/Makefile | 74 ++------------------ src/mesa/sources | 56 +-------------- 13 files changed, 247 insertions(+), 141 deletions(-) create mode 100644 src/gallium/auxiliary/cso_cache/Makefile delete mode 100644 src/gallium/auxiliary/tgsi/exec/Makefile create mode 100644 src/gallium/auxiliary/util/Makefile create mode 100644 src/gallium/winsys/Makefile create mode 100644 src/gallium/winsys/xlib/Makefile (limited to 'src') diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 83b25f9b47..6ad58c205c 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -20,6 +20,7 @@ INCLUDES = \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ -I$(TOP)/include \ $(DRIVER_INCLUDES) diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index da68498aa1..eaa0f2fe4e 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -2,11 +2,7 @@ TOP = ../../.. include $(TOP)/configs/current -ifeq ($(CONFIG_NAME), linux-llvm) -LLVM_DIR = llvm -endif - -SUBDIRS = pipebuffer $(LLVM_DIR) +SUBDIRS = $(GALLIUM_AUXILIARY_DIRS) default: subdirs diff --git a/src/gallium/auxiliary/cso_cache/Makefile b/src/gallium/auxiliary/cso_cache/Makefile new file mode 100644 index 0000000000..8248b097fd --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/Makefile @@ -0,0 +1,18 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = cso_cache + +DRIVER_SOURCES = \ + cso_cache.c \ + cso_hash.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index fe9b150f30..c56b63d85b 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -1,2 +1,39 @@ -default: - cd ../../../mesa ; make +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = draw + +DRIVER_SOURCES = \ + draw_clip.c \ + draw_vs_exec.c \ + draw_vs_sse.c \ + draw_vs_llvm.c \ + draw_context.c\ + draw_cull.c \ + draw_debug.c \ + draw_flatshade.c \ + draw_offset.c \ + draw_prim.c \ + draw_stipple.c \ + draw_twoside.c \ + draw_unfilled.c \ + draw_validate.c \ + draw_vbuf.c \ + draw_vertex.c \ + draw_vertex_cache.c \ + draw_vertex_fetch.c \ + draw_vertex_shader.c \ + draw_vf.c \ + draw_vf_generic.c \ + draw_vf_sse.c \ + draw_wide_prims.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index 12a8bd0409..c10ab396d8 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -1,3 +1,23 @@ -default: - cd ../.. ; make + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = tgsi + +DRIVER_SOURCES = \ + exec/tgsi_exec.c \ + exec/tgsi_sse2.c \ + util/tgsi_build.c \ + util/tgsi_dump.c \ + util/tgsi_parse.c \ + util/tgsi_util.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: diff --git a/src/gallium/auxiliary/tgsi/exec/Makefile b/src/gallium/auxiliary/tgsi/exec/Makefile deleted file mode 100644 index eb8b14e0e8..0000000000 --- a/src/gallium/auxiliary/tgsi/exec/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -default: - cd ../../.. ; make - diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile new file mode 100644 index 0000000000..b8cb148c4f --- /dev/null +++ b/src/gallium/auxiliary/util/Makefile @@ -0,0 +1,20 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = util + +DRIVER_SOURCES = \ + p_debug.c \ + p_tile.c \ + p_util.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/Makefile b/src/gallium/drivers/Makefile index c0345a9cb5..8dcfb18a16 100644 --- a/src/gallium/drivers/Makefile +++ b/src/gallium/drivers/Makefile @@ -2,11 +2,7 @@ TOP = ../../.. include $(TOP)/configs/current -ifeq ($(CONFIG_NAME), linux-cell) -CELL_DIR = cell -endif - -SUBDIRS = softpipe i915simple i965simple failover pipebuffer $(CELL_DIR) +SUBDIRS = softpipe i915simple i965simple failover default: subdirs diff --git a/src/gallium/winsys/Makefile b/src/gallium/winsys/Makefile new file mode 100644 index 0000000000..3dc5ea5744 --- /dev/null +++ b/src/gallium/winsys/Makefile @@ -0,0 +1,20 @@ +TOP = ../../.. +include $(TOP)/configs/current + + +SUBDIRS = $(GALLIUM_WINSYS_DIRS) + + +default: subdirs + + +subdirs: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + + +clean: + rm -f `find . -name \*.[oa]` diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 2a261ed669..65a93bd53e 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -1,7 +1,9 @@ # -*-makefile-*- -MESA_MODULES = $(TOP)/src/mesa/libmesa.a - +MESA_MODULES = \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + COMMON_GALLIUM_SOURCES = \ $(TOP)/src/mesa/drivers/dri/common/utils.c \ $(TOP)/src/mesa/drivers/dri/common/vblank.c \ diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile new file mode 100644 index 0000000000..2664ac47ce --- /dev/null +++ b/src/gallium/winsys/xlib/Makefile @@ -0,0 +1,113 @@ +# src/mesa/Makefile + +TOP = ../../../.. +include $(TOP)/configs/current + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary + +X11_DRIVER_SOURCES = \ + glxapi.c \ + fakeglx.c \ + xfonts.c \ + xm_api.c \ + xm_winsys.c \ + xm_winsys_aub.c \ + brw_aub.c + + +GL_MAJOR = 1 +GL_MINOR = 5 +GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) + + +PIPE_LIB = \ + $(GALLIUM_DRIVERS) \ + $(TOP)/src/mesa/libglapi.a \ + $(TOP)/src/mesa/libmesa.a \ + $(GALLIUM_AUXILIARIES) + +ifeq ($(CONFIG_NAME), linux-cell) +CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a +CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a +endif + +ifeq ($(CONFIG_NAME), linux-llvm) +LLVM_LIB = $(TOP)/src/gallium/auxiliary/llvm/libgallivm.a +endif + + +.SUFFIXES : .cpp + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + +default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) + + +###################################################################### +# Stand-alone Mesa libGL and libOSMesa +STAND_ALONE_DRIVER_SOURCES = \ + $(X11_DRIVER_SOURCES) + +STAND_ALONE_DRIVER_OBJECTS = $(STAND_ALONE_DRIVER_SOURCES:.c=.o) + +STAND_ALONE_OBJECTS = \ + $(STAND_ALONE_DRIVER_OBJECTS) + +# Make the GL library +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(LLVM_LIB) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) + $(TOP)/bin/mklib -o $(GL_LIB) \ + -linker "$(CC)" \ + -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ + -install $(TOP)/$(LIB_DIR) \ + $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ + --start-group $(PIPE_LIB) $(LLVM_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + + +###################################################################### +# Generic stuff + +depend: $(ALL_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend # workaround oops on gutsy?!? + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \ + > /dev/null 2>/dev/null + + +install: default + $(INSTALL) -d $(INSTALL_DIR)/include/GL + $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL + @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ + $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ + fi + +## NOT INSTALLED YET: +## $(INSTALL) -d $(INSTALL_DIR)/include/GLES +## $(INSTALL) -m 644 include/GLES/*.h $(INSTALL_DIR)/include/GLES + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h + +clean: + -rm -f *.o + + +include depend diff --git a/src/mesa/Makefile b/src/mesa/Makefile index c8cb2b592f..86a9cf0b88 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -11,19 +11,6 @@ GL_MINOR = 5 GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) -PIPE_LIB = \ - $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ - $(TOP)/src/gallium/drivers/i965simple/libi965simple.a - -ifeq ($(CONFIG_NAME), linux-cell) -CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a -CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a -endif - -ifeq ($(CONFIG_NAME), linux-llvm) -LLVM_LIB = $(TOP)/src/gallium/auxiliary/llvm/libgallivm.a -endif - .SUFFIXES : .cpp .c.o: @@ -36,33 +23,14 @@ endif $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ -# Figure out what to make here -default: - @if [ "${DRIVER_DIRS}" = "dri" ] ; then \ - $(MAKE) linux-solo ; \ - elif [ "${DRIVER_DIRS}" = "osmesa" ] ; then \ - $(MAKE) osmesa-only ; \ - elif [ "$(DRIVER_DIRS)" = "beos" ]; then \ - $(MAKE) beos ; \ - elif [ "$(DRIVER_DIRS)" = "directfb" ]; then \ - $(MAKE) directfb ; \ - elif [ "$(DRIVER_DIRS)" = "fbdev osmesa" ]; then \ - $(MAKE) fbdev ; $(MAKE) osmesa-only ; \ - else \ - $(MAKE) stand-alone ; \ - fi - +default: depend subdirs libmesa.a -###################################################################### -# BeOS driver target - -beos: depend subdirs libmesa.a - cd drivers/beos; $(MAKE) +ifneq ($(DRIVER_DIRS),dri) +default: libglapi.a +endif ###################################################################### -# Linux DRI drivers - # Make archive of core object files libmesa.a: $(SOLO_OBJECTS) @ $(TOP)/bin/mklib -o mesa -static $(SOLO_OBJECTS); @@ -70,32 +38,8 @@ libmesa.a: $(SOLO_OBJECTS) mimeset -f "$@" ; \ fi -linux-solo: depend subdirs libmesa.a - cd $(TOP)/src/gallium/winsys/dri ; $(MAKE) - - -##################################################################### -# Stand-alone Mesa libGL, no built-in drivers (DirectFB) - -libgl-core: $(CORE_OBJECTS) - @ $(TOP)/bin/mklib -o $(GL_LIB) \ - -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ - -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) $(CORE_OBJECTS) \ - $(GL_LIB_DEPS) - -directfb: depend subdirs libgl-core - cd drivers/directfb ; $(MAKE) - - -##################################################################### -# fbdev Mesa driver (libGL.so) - -fbdev: $(CORE_OBJECTS) $(FBDEV_DRIVER_OBJECTS) $(COMMON_DRIVER_OBJECTS) - @ $(TOP)/bin/mklib -o $(GL_LIB) \ - -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ - -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ - $(CORE_OBJECTS) $(FBDEV_DRIVER_OBJECTS) \ - $(COMMON_DRIVER_OBJECTS) $(GL_LIB_DEPS) +libglapi.a: $(GLAPI_OBJECTS) + @ $(TOP)/bin/mklib -o glapi -static $(GLAPI_OBJECTS) ###################################################################### @@ -176,9 +120,6 @@ install: default @if [ -e $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) ]; then \ $(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* $(INSTALL_DIR)/$(LIB_DIR); \ fi - @if [ "${DRIVER_DIRS}" = "dri" ] ; then \ - cd $(TOP)/gallium/winsys/dri ; $(MAKE) install ; \ - fi ## NOT INSTALLED YET: ## $(INSTALL) -d $(INSTALL_DIR)/include/GLES @@ -192,9 +133,8 @@ tags: clean: -rm -f */*.o -rm -f */*/*.o - -rm -f depend depend.bak libmesa.a + -rm -f depend depend.bak libmesa.a libglapi.a -rm -f drivers/*/*.o - (cd drivers/dri && $(MAKE) clean) (cd x86 && $(MAKE) clean) (cd x86-64 && $(MAKE) clean) diff --git a/src/mesa/sources b/src/mesa/sources index f83d247a1e..0d185fd5f3 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -156,51 +156,6 @@ VF_SOURCES = \ vf/vf_generic.c \ vf/vf_sse.c - -DRAW_SOURCES = \ - $(TOP)/src/gallium/auxiliary/draw/draw_clip.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vs_exec.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vs_sse.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vs_llvm.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_context.c\ - $(TOP)/src/gallium/auxiliary/draw/draw_cull.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_debug.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_flatshade.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_offset.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_prim.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_stipple.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_twoside.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_unfilled.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_validate.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vbuf.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vertex.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vertex_cache.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vertex_fetch.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vertex_shader.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vf.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vf_generic.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_vf_sse.c \ - $(TOP)/src/gallium/auxiliary/draw/draw_wide_prims.c - -TGSIEXEC_SOURCES = \ - $(TOP)/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c \ - $(TOP)/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c - -TGSIUTIL_SOURCES = \ - $(TOP)/src/gallium/auxiliary/tgsi/util/tgsi_build.c \ - $(TOP)/src/gallium/auxiliary/tgsi/util/tgsi_dump.c \ - $(TOP)/src/gallium/auxiliary/tgsi/util/tgsi_parse.c \ - $(TOP)/src/gallium/auxiliary/tgsi/util/tgsi_util.c - -STATECACHE_SOURCES = \ - $(TOP)/src/gallium/auxiliary/cso_cache/cso_hash.c \ - $(TOP)/src/gallium/auxiliary/cso_cache/cso_cache.c - -PIPEUTIL_SOURCES = \ - $(TOP)/src/gallium/auxiliary/util/p_debug.c \ - $(TOP)/src/gallium/auxiliary/util/p_tile.c \ - $(TOP)/src/gallium/auxiliary/util/p_util.c - STATETRACKER_SOURCES = \ state_tracker/st_atom.c \ state_tracker/st_atom_blend.c \ @@ -229,7 +184,7 @@ STATETRACKER_SOURCES = \ state_tracker/st_cb_readpixels.c \ state_tracker/st_cb_strings.c \ state_tracker/st_cb_texture.c \ - state_tracker/st_cache.c \ + state_tracker/st_cache.c \ state_tracker/st_context.c \ state_tracker/st_debug.c \ state_tracker/st_draw.c \ @@ -333,15 +288,6 @@ SPARC_API = \ __COMMON_DRIVER_SOURCES = \ drivers/common/driverfuncs.c -X11_DRIVER_SOURCES = \ - $(TOP)/src/gallium/winsys/xlib/glxapi.c \ - $(TOP)/src/gallium/winsys/xlib/fakeglx.c \ - $(TOP)/src/gallium/winsys/xlib/xfonts.c \ - $(TOP)/src/gallium/winsys/xlib/xm_api.c \ - $(TOP)/src/gallium/winsys/xlib/xm_winsys.c \ - $(TOP)/src/gallium/winsys/xlib/xm_winsys_aub.c \ - $(TOP)/src/gallium/winsys/xlib/brw_aub.c - OSMESA_DRIVER_SOURCES = \ drivers/osmesa/osmesa.c -- cgit v1.2.3 From 39fe5851a57a7218eafce7dab971738bdb780166 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 15:07:17 +0900 Subject: Actually use GALLIUM_DRIVER_DIRS. --- src/gallium/drivers/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/drivers/Makefile b/src/gallium/drivers/Makefile index 8dcfb18a16..6161cb6ff8 100644 --- a/src/gallium/drivers/Makefile +++ b/src/gallium/drivers/Makefile @@ -2,7 +2,7 @@ TOP = ../../.. include $(TOP)/configs/current -SUBDIRS = softpipe i915simple i965simple failover +SUBDIRS = $(GALLIUM_DRIVER_DIRS) default: subdirs -- cgit v1.2.3 From 8450b14676a2f5c6423b16bc4bc7a1ec5a6a987e Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 15:37:52 +0900 Subject: Cleanup depend files. --- src/gallium/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gallium/Makefile b/src/gallium/Makefile index 89e068a449..568747e157 100644 --- a/src/gallium/Makefile +++ b/src/gallium/Makefile @@ -18,3 +18,4 @@ subdirs: clean: rm -f `find . -name \*.[oa]` + rm -f `find . -name depend` -- cgit v1.2.3 From 33ceb6716a2166db75659fa66d85fb4cfb9633c7 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 10:52:44 +0000 Subject: Update scons build for new code layout. --- SConstruct | 7 +- src/SConscript | 7 ++ src/gallium/SConscript | 23 +++- src/gallium/auxiliary/cso_cache/SConscript | 10 ++ src/gallium/auxiliary/draw/SConscript | 31 +++++ src/gallium/auxiliary/pipebuffer/SConscript | 14 +++ src/gallium/auxiliary/tgsi/SConscript | 14 +++ src/gallium/auxiliary/util/SConscript | 11 ++ src/gallium/drivers/failover/SConscript | 13 +++ src/gallium/winsys/SConscript | 10 ++ src/gallium/winsys/dri/SConscript | 51 +++++++++ src/gallium/winsys/dri/intel/SConscript | 14 +-- src/gallium/winsys/xlib/SConscript | 28 +++++ src/mesa/SConscript | 170 ++-------------------------- src/mesa/drivers/dri/SConscript | 48 -------- 15 files changed, 229 insertions(+), 222 deletions(-) create mode 100644 src/SConscript create mode 100644 src/gallium/auxiliary/cso_cache/SConscript create mode 100644 src/gallium/auxiliary/draw/SConscript create mode 100644 src/gallium/auxiliary/pipebuffer/SConscript create mode 100644 src/gallium/auxiliary/tgsi/SConscript create mode 100644 src/gallium/auxiliary/util/SConscript create mode 100644 src/gallium/drivers/failover/SConscript create mode 100644 src/gallium/winsys/SConscript create mode 100644 src/gallium/winsys/dri/SConscript create mode 100644 src/gallium/winsys/xlib/SConscript delete mode 100644 src/mesa/drivers/dri/SConscript (limited to 'src') diff --git a/SConstruct b/SConstruct index 22a4072c93..1126aff21b 100644 --- a/SConstruct +++ b/SConstruct @@ -108,7 +108,10 @@ env.Append(CPPPATH = [ '#/include', '#/src/mesa', '#/src/mesa/main', - '#/src/mesa/pipe', + '#/src/gallium/include/pipe', + '#/src/gallium/include', + '#/src/gallium/auxiliary', + '#/src/gallium/drivers', ]) @@ -222,7 +225,7 @@ build_dir = os.path.join(build_topdir, build_subdir) # http://www.scons.org/wiki/SimultaneousVariantBuilds SConscript( - 'src/mesa/SConscript', + 'src/SConscript', build_dir = build_dir, duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html ) diff --git a/src/SConscript b/src/SConscript new file mode 100644 index 0000000000..5b09943894 --- /dev/null +++ b/src/SConscript @@ -0,0 +1,7 @@ +Import('*') + +SConscript([ + 'gallium/SConscript', + 'mesa/SConscript', + 'gallium/winsys/SConscript', +]) diff --git a/src/gallium/SConscript b/src/gallium/SConscript index d9c20e0100..a835f6d661 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -1,9 +1,24 @@ Import('*') -#env = env.Clone() +env = env.Clone() + +auxiliaries = [] + +Export('auxiliaries') + SConscript([ - 'softpipe/SConscript', - 'i915simple/SConscript', - 'i965simple/SConscript', + # NOTE: order matters! + 'auxiliary/util/SConscript', + 'auxiliary/tgsi/SConscript', + 'auxiliary/cso_cache/SConscript', + 'auxiliary/draw/SConscript', + #'auxiliary/llvm/SConscript', + 'auxiliary/pipebuffer/SConscript', + + 'drivers/softpipe/SConscript', + 'drivers/i915simple/SConscript', + 'drivers/i965simple/SConscript', + 'drivers/failover/SConscript', + #'drivers/cell/SConscript', ]) diff --git a/src/gallium/auxiliary/cso_cache/SConscript b/src/gallium/auxiliary/cso_cache/SConscript new file mode 100644 index 0000000000..9751881613 --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/SConscript @@ -0,0 +1,10 @@ +Import('*') + +cso_cache = env.ConvenienceLibrary( + target = 'cso_cache', + source = [ + 'cso_cache.c', + 'cso_hash.c', + ]) + +auxiliaries.insert(0, cso_cache) diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript new file mode 100644 index 0000000000..8e3a8caa74 --- /dev/null +++ b/src/gallium/auxiliary/draw/SConscript @@ -0,0 +1,31 @@ +Import('*') + +draw = env.ConvenienceLibrary( + target = 'draw', + source = [ + 'draw_clip.c', + 'draw_vs_exec.c', + 'draw_vs_sse.c', + 'draw_vs_llvm.c', + 'draw_context.c', + 'draw_cull.c', + 'draw_debug.c', + 'draw_flatshade.c', + 'draw_offset.c', + 'draw_prim.c', + 'draw_stipple.c', + 'draw_twoside.c', + 'draw_unfilled.c', + 'draw_validate.c', + 'draw_vbuf.c', + 'draw_vertex.c', + 'draw_vertex_cache.c', + 'draw_vertex_fetch.c', + 'draw_vertex_shader.c', + 'draw_vf.c', + 'draw_vf_generic.c', + 'draw_vf_sse.c', + 'draw_wide_prims.c', + ]) + +auxiliaries.insert(0, draw) diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript new file mode 100644 index 0000000000..3d41fd84a6 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -0,0 +1,14 @@ +Import('*') + +pipebuffer = env.ConvenienceLibrary( + target = 'pipebuffer', + source = [ + 'pb_buffer_fenced.c', + 'pb_buffer_malloc.c', + 'pb_bufmgr_fenced.c', + 'pb_bufmgr_mm.c', + 'pb_bufmgr_pool.c', + 'pb_winsys.c', + ]) + +auxiliaries.insert(0, pipebuffer) diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript new file mode 100644 index 0000000000..8464bfe944 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -0,0 +1,14 @@ +Import('*') + +tgsi = env.ConvenienceLibrary( + target = 'tgsi', + source = [ + 'exec/tgsi_exec.c', + 'exec/tgsi_sse2.c', + 'util/tgsi_build.c', + 'util/tgsi_dump.c', + 'util/tgsi_parse.c', + 'util/tgsi_util.c', + ]) + +auxiliaries.insert(0, tgsi) diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript new file mode 100644 index 0000000000..b126cf44d6 --- /dev/null +++ b/src/gallium/auxiliary/util/SConscript @@ -0,0 +1,11 @@ +Import('*') + +util = env.ConvenienceLibrary( + target = 'util', + source = [ + 'p_debug.c', + 'p_tile.c', + 'p_util.c', + ]) + +auxiliaries.insert(0, util) diff --git a/src/gallium/drivers/failover/SConscript b/src/gallium/drivers/failover/SConscript new file mode 100644 index 0000000000..f8e9b1b491 --- /dev/null +++ b/src/gallium/drivers/failover/SConscript @@ -0,0 +1,13 @@ +Import('*') + +env = env.Clone() + +failover = env.ConvenienceLibrary( + target = 'failover', + source = [ + 'fo_state.c', + 'fo_state_emit.c', + 'fo_context.c', + ]) + +Export('failover') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript new file mode 100644 index 0000000000..32215d8d58 --- /dev/null +++ b/src/gallium/winsys/SConscript @@ -0,0 +1,10 @@ +Import('*') + +if dri: + SConscript([ + 'dri/SConscript', + ]) +else: + SConscript([ + 'xlib/SConscript', + ]) diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript new file mode 100644 index 0000000000..8c56ce917c --- /dev/null +++ b/src/gallium/winsys/dri/SConscript @@ -0,0 +1,51 @@ +Import('*') + +drienv = env.Clone() + +drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', +]) + +drienv.ParseConfig('pkg-config --cflags --libs libdrm') + +COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', +] + +COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', +] + +Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', +]) + +# TODO: Installation +#install: $(LIBNAME) +# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) +# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + +SConscript([ + 'intel/SConscript', +]) diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index a7cc10450e..525ba580e8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -9,11 +9,6 @@ env.Append(CPPPATH = [ #MINIGLX_SOURCES = server/intel_dri.c -pipe_drivers = [ - softpipe, - i915simple -] - DRIVER_SOURCES = [ 'intel_winsys_pipe.c', 'intel_winsys_softpipe.c', @@ -31,11 +26,14 @@ sources = \ COMMON_BM_SOURCES + \ DRIVER_SOURCES -# DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ -# && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +drivers = [ + softpipe, + i915simple +] +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = pipe_drivers + env['LIBS'], + LIBS = mesa + drivers + auxiliaries + env['LIBS'], ) \ No newline at end of file diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript new file mode 100644 index 0000000000..f8aa5ef945 --- /dev/null +++ b/src/gallium/winsys/xlib/SConscript @@ -0,0 +1,28 @@ +####################################################################### +# SConscript for xlib winsys + +Import('*') + + +sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', +] + +drivers = [ + softpipe, + i915simple, + i965simple, +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], +) diff --git a/src/mesa/SConscript b/src/mesa/SConscript index faf8c84872..a828133580 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -1,7 +1,5 @@ ####################################################################### -# SConscript for mesa -# -# TODO: Split this into per-module SConscripts +# SConscript for Mesa Import('*') @@ -116,53 +114,6 @@ VF_SOURCES = [ 'vf/vf_sse.c', ] -DRAW_SOURCES = [ - 'pipe/draw/draw_clip.c', - 'pipe/draw/draw_context.c', - 'pipe/draw/draw_cull.c', - 'pipe/draw/draw_debug.c', - 'pipe/draw/draw_flatshade.c', - 'pipe/draw/draw_offset.c', - 'pipe/draw/draw_prim.c', - 'pipe/draw/draw_stipple.c', - 'pipe/draw/draw_twoside.c', - 'pipe/draw/draw_unfilled.c', - 'pipe/draw/draw_validate.c', - 'pipe/draw/draw_vbuf.c', - 'pipe/draw/draw_vertex.c', - 'pipe/draw/draw_vertex_cache.c', - 'pipe/draw/draw_vertex_fetch.c', - 'pipe/draw/draw_vertex_shader.c', - 'pipe/draw/draw_vertex_shader_llvm.c', - 'pipe/draw/draw_vf.c', - 'pipe/draw/draw_vf_generic.c', - 'pipe/draw/draw_vf_sse.c', - 'pipe/draw/draw_wide_prims.c', -] - -TGSIEXEC_SOURCES = [ - 'pipe/tgsi/exec/tgsi_exec.c', - 'pipe/tgsi/exec/tgsi_sse2.c', -] - -TGSIUTIL_SOURCES = [ - 'pipe/tgsi/util/tgsi_build.c', - 'pipe/tgsi/util/tgsi_dump.c', - 'pipe/tgsi/util/tgsi_parse.c', - 'pipe/tgsi/util/tgsi_util.c', -] - -STATECACHE_SOURCES = [ - 'pipe/cso_cache/cso_hash.c', - 'pipe/cso_cache/cso_cache.c', -] - -PIPEUTIL_SOURCES = [ - 'pipe/util/p_debug.c', - 'pipe/util/p_tile.c', - 'pipe/util/p_util.c', -] - STATETRACKER_SOURCES = [ 'state_tracker/st_atom.c', 'state_tracker/st_atom_blend.c', @@ -311,126 +262,25 @@ else: ASM_SOURCES = [] API_SOURCES = [] - -####################################################################### -# Driver sources - - -X11_DRIVER_SOURCES = [ - 'pipe/xlib/glxapi.c', - 'pipe/xlib/fakeglx.c', - 'pipe/xlib/xfonts.c', - 'pipe/xlib/xm_api.c', - 'pipe/xlib/xm_winsys.c', - 'pipe/xlib/xm_winsys_aub.c', - 'pipe/xlib/brw_aub.c', -] - -OSMESA_DRIVER_SOURCES = [ - 'drivers/osmesa/osmesa.c', -] - -GLIDE_DRIVER_SOURCES = [ - 'drivers/glide/fxapi.c', - 'drivers/glide/fxdd.c', - 'drivers/glide/fxddspan.c', - 'drivers/glide/fxddtex.c', - 'drivers/glide/fxsetup.c', - 'drivers/glide/fxtexman.c', - 'drivers/glide/fxtris.c', - 'drivers/glide/fxvb.c', - 'drivers/glide/fxglidew.c', - 'drivers/glide/fxg.c', -] - -SVGA_DRIVER_SOURCES = [ - 'drivers/svga/svgamesa.c', - 'drivers/svga/svgamesa8.c', - 'drivers/svga/svgamesa15.c', - 'drivers/svga/svgamesa16.c', - 'drivers/svga/svgamesa24.c', - 'drivers/svga/svgamesa32.c', -] - -FBDEV_DRIVER_SOURCES = [ - 'drivers/fbdev/glfbdev.c', -] - - -### All the core C sources - SOLO_SOURCES = \ MAIN_SOURCES + \ MATH_SOURCES + \ VBO_SOURCES + \ VF_SOURCES + \ - DRAW_SOURCES + \ - TGSIEXEC_SOURCES + \ - TGSIUTIL_SOURCES + \ - PIPEUTIL_SOURCES + \ - STATECACHE_SOURCES + \ STATETRACKER_SOURCES + \ SHADER_SOURCES + \ ASM_SOURCES + \ SLANG_SOURCES -CORE_SOURCES = \ - GLAPI_SOURCES + API_SOURCES + \ - SOLO_SOURCES - -ALL_SOURCES = \ - GLAPI_SOURCES + API_SOURCES + \ - SOLO_SOURCES + \ - ASM_SOURCES + \ - X11_DRIVER_SOURCES + \ - FBDEV_DRIVER_SOURCES + \ - OSMESA_DRIVER_SOURCES - - -###################################################################### -# Gallium sources - -SConscript([ - 'pipe/SConscript', -]) - - -###################################################################### -# libGL +mesa = env.ConvenienceLibrary( + target = 'mesa', + source = SOLO_SOURCES, +) +Export('mesa') if not dri: - STAND_ALONE_DRIVER_SOURCES = \ - CORE_SOURCES + \ - X11_DRIVER_SOURCES - - Import( - 'softpipe', - 'i915simple', - 'i965simple' + glapi = env.ConvenienceLibrary( + target = 'glapi', + source = GLAPI_SOURCES + API_SOURCES, ) - - pipe_drivers = [ - softpipe, - i965simple - ] - - env.SharedLibrary( - target ='GL', - source = STAND_ALONE_DRIVER_SOURCES, - LIBS = [softpipe, i965simple] + env['LIBS'], - ) - - -###################################################################### -# Driver sources - -if dri: - mesa = env.ConvenienceLibrary( - target = 'mesa', - source = SOLO_SOURCES, - ) - env.Prepend(LIBS = [mesa]) - - SConscript([ - 'drivers/dri/SConscript', - ]) + Export('glapi') diff --git a/src/mesa/drivers/dri/SConscript b/src/mesa/drivers/dri/SConscript deleted file mode 100644 index d32bd08669..0000000000 --- a/src/mesa/drivers/dri/SConscript +++ /dev/null @@ -1,48 +0,0 @@ -Import('*') - -drienv = env.Clone() - -drienv.Replace(CPPPATH = [ - '#src/mesa/drivers/dri/common', - '#include', - '#include/GL/internal', - '#src/mesa', - '#src/mesa/main', - '#src/mesa/glapi', - '#src/mesa/math', - '#src/mesa/transform', - '#src/mesa/shader', - '#src/mesa/swrast', - '#src/mesa/swrast_setup', - '#src/egl/main', - '#src/egl/drivers/dri', -]) - -drienv.ParseConfig('pkg-config --cflags --libs libdrm') - -COMMON_GALLIUM_SOURCES = [ - '../common/utils.c', - '../common/vblank.c', - '../common/dri_util.c', - '../common/xmlconfig.c', -] - -COMMON_BM_SOURCES = [ - '../common/dri_bufmgr.c', - '../common/dri_drmpool.c', -] - -Export([ - 'drienv', - 'COMMON_GALLIUM_SOURCES', - 'COMMON_BM_SOURCES', -]) - -# TODO: Installation -#install: $(LIBNAME) -# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) -# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - -SConscript([ - 'intel_winsys/SConscript', -]) -- cgit v1.2.3 From 687a8b96ef13658bbe779d0011ce1144844f1972 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 20:02:42 +0900 Subject: Standardize on using the pipe/ include prefix. --- SConstruct | 1 - src/gallium/Makefile.template | 1 - src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 10 +++++----- src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c | 4 ++-- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 8 ++++---- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 10 +++++----- src/gallium/drivers/i915simple/i915_state_immediate.c | 2 +- src/gallium/drivers/i915simple/i915_state_inlines.h | 4 ++-- src/gallium/drivers/softpipe/sp_state_surface.c | 2 +- 9 files changed, 20 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/SConstruct b/SConstruct index 1126aff21b..4fb51f2e6d 100644 --- a/SConstruct +++ b/SConstruct @@ -108,7 +108,6 @@ env.Append(CPPPATH = [ '#/include', '#/src/mesa', '#/src/mesa/main', - '#/src/gallium/include/pipe', '#/src/gallium/include', '#/src/gallium/auxiliary', '#/src/gallium/drivers', diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 6ad58c205c..6698212e77 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -16,7 +16,6 @@ OBJECTS = $(C_SOURCES:.c=.o) \ INCLUDES = \ -I. \ -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/include/pipe \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index f4fc3f6d71..bc85c4b19f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -36,11 +36,11 @@ #include "linked_list.h" -#include "p_compiler.h" -#include "p_debug.h" -#include "p_winsys.h" -#include "p_thread.h" -#include "p_util.h" +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_winsys.h" +#include "pipe/p_thread.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index c535d3276c..bffca5b244 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -34,8 +34,8 @@ */ -#include "p_debug.h" -#include "p_util.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 8b1b51c0e2..969aab51b5 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -36,10 +36,10 @@ #include "linked_list.h" -#include "p_defines.h" -#include "p_debug.h" -#include "p_thread.h" -#include "p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 04477a865a..beb145b7cb 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -37,11 +37,11 @@ #include "linked_list.h" -#include "p_compiler.h" -#include "p_debug.h" -#include "p_thread.h" -#include "p_defines.h" -#include "p_util.h" +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c index 07031fc6c5..dfbbcab624 100644 --- a/src/gallium/drivers/i915simple/i915_state_immediate.c +++ b/src/gallium/drivers/i915simple/i915_state_immediate.c @@ -33,7 +33,7 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_reg.h" -#include "p_util.h" +#include "pipe/p_util.h" /* All state expressable with the LOAD_STATE_IMMEDIATE_1 packet. diff --git a/src/gallium/drivers/i915simple/i915_state_inlines.h b/src/gallium/drivers/i915simple/i915_state_inlines.h index 0934ac79a4..378de8f9c4 100644 --- a/src/gallium/drivers/i915simple/i915_state_inlines.h +++ b/src/gallium/drivers/i915simple/i915_state_inlines.h @@ -28,8 +28,8 @@ #ifndef I915_STATE_INLINES_H #define I915_STATE_INLINES_H -#include "p_compiler.h" -#include "p_defines.h" +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" #include "i915_reg.h" diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index e2c6893e9f..124b18b708 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -27,7 +27,7 @@ /* Authors: Keith Whitwell */ -#include "p_inlines.h" +#include "pipe/p_inlines.h" #include "sp_context.h" #include "sp_state.h" -- cgit v1.2.3 From 3f3b09d6d86cfd277c5837d15466ee703897aa3d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 20:05:06 +0900 Subject: Rename llvm -> gallivm. Following the directory == library name policy simplifies the build system. --- src/gallium/auxiliary/gallivm/Makefile | 85 ++ src/gallium/auxiliary/gallivm/gallivm.cpp | 327 ++++++ src/gallium/auxiliary/gallivm/gallivm.h | 103 ++ src/gallium/auxiliary/gallivm/gallivm_builtins.cpp | 567 +++++++++ src/gallium/auxiliary/gallivm/gallivm_cpu.cpp | 202 ++++ src/gallium/auxiliary/gallivm/gallivm_p.h | 110 ++ src/gallium/auxiliary/gallivm/instructions.cpp | 889 ++++++++++++++ src/gallium/auxiliary/gallivm/instructions.h | 152 +++ src/gallium/auxiliary/gallivm/instructionssoa.cpp | 121 ++ src/gallium/auxiliary/gallivm/instructionssoa.h | 74 ++ src/gallium/auxiliary/gallivm/llvm_builtins.c | 115 ++ src/gallium/auxiliary/gallivm/loweringpass.cpp | 17 + src/gallium/auxiliary/gallivm/loweringpass.h | 15 + src/gallium/auxiliary/gallivm/storage.cpp | 364 ++++++ src/gallium/auxiliary/gallivm/storage.h | 133 +++ src/gallium/auxiliary/gallivm/storagesoa.cpp | 389 +++++++ src/gallium/auxiliary/gallivm/storagesoa.h | 111 ++ src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 1221 ++++++++++++++++++++ src/gallium/auxiliary/gallivm/tgsitollvm.h | 20 + src/gallium/auxiliary/llvm/Makefile | 85 -- src/gallium/auxiliary/llvm/gallivm.cpp | 327 ------ src/gallium/auxiliary/llvm/gallivm.h | 103 -- src/gallium/auxiliary/llvm/gallivm_builtins.cpp | 567 --------- src/gallium/auxiliary/llvm/gallivm_cpu.cpp | 202 ---- src/gallium/auxiliary/llvm/gallivm_p.h | 110 -- src/gallium/auxiliary/llvm/instructions.cpp | 889 -------------- src/gallium/auxiliary/llvm/instructions.h | 152 --- src/gallium/auxiliary/llvm/instructionssoa.cpp | 121 -- src/gallium/auxiliary/llvm/instructionssoa.h | 74 -- src/gallium/auxiliary/llvm/llvm_builtins.c | 115 -- src/gallium/auxiliary/llvm/loweringpass.cpp | 17 - src/gallium/auxiliary/llvm/loweringpass.h | 15 - src/gallium/auxiliary/llvm/storage.cpp | 364 ------ src/gallium/auxiliary/llvm/storage.h | 133 --- src/gallium/auxiliary/llvm/storagesoa.cpp | 389 ------- src/gallium/auxiliary/llvm/storagesoa.h | 111 -- src/gallium/auxiliary/llvm/tgsitollvm.cpp | 1221 -------------------- src/gallium/auxiliary/llvm/tgsitollvm.h | 20 - 38 files changed, 5015 insertions(+), 5015 deletions(-) create mode 100644 src/gallium/auxiliary/gallivm/Makefile create mode 100644 src/gallium/auxiliary/gallivm/gallivm.cpp create mode 100644 src/gallium/auxiliary/gallivm/gallivm.h create mode 100644 src/gallium/auxiliary/gallivm/gallivm_builtins.cpp create mode 100644 src/gallium/auxiliary/gallivm/gallivm_cpu.cpp create mode 100644 src/gallium/auxiliary/gallivm/gallivm_p.h create mode 100644 src/gallium/auxiliary/gallivm/instructions.cpp create mode 100644 src/gallium/auxiliary/gallivm/instructions.h create mode 100644 src/gallium/auxiliary/gallivm/instructionssoa.cpp create mode 100644 src/gallium/auxiliary/gallivm/instructionssoa.h create mode 100644 src/gallium/auxiliary/gallivm/llvm_builtins.c create mode 100644 src/gallium/auxiliary/gallivm/loweringpass.cpp create mode 100644 src/gallium/auxiliary/gallivm/loweringpass.h create mode 100644 src/gallium/auxiliary/gallivm/storage.cpp create mode 100644 src/gallium/auxiliary/gallivm/storage.h create mode 100644 src/gallium/auxiliary/gallivm/storagesoa.cpp create mode 100644 src/gallium/auxiliary/gallivm/storagesoa.h create mode 100644 src/gallium/auxiliary/gallivm/tgsitollvm.cpp create mode 100644 src/gallium/auxiliary/gallivm/tgsitollvm.h delete mode 100644 src/gallium/auxiliary/llvm/Makefile delete mode 100644 src/gallium/auxiliary/llvm/gallivm.cpp delete mode 100644 src/gallium/auxiliary/llvm/gallivm.h delete mode 100644 src/gallium/auxiliary/llvm/gallivm_builtins.cpp delete mode 100644 src/gallium/auxiliary/llvm/gallivm_cpu.cpp delete mode 100644 src/gallium/auxiliary/llvm/gallivm_p.h delete mode 100644 src/gallium/auxiliary/llvm/instructions.cpp delete mode 100644 src/gallium/auxiliary/llvm/instructions.h delete mode 100644 src/gallium/auxiliary/llvm/instructionssoa.cpp delete mode 100644 src/gallium/auxiliary/llvm/instructionssoa.h delete mode 100644 src/gallium/auxiliary/llvm/llvm_builtins.c delete mode 100644 src/gallium/auxiliary/llvm/loweringpass.cpp delete mode 100644 src/gallium/auxiliary/llvm/loweringpass.h delete mode 100644 src/gallium/auxiliary/llvm/storage.cpp delete mode 100644 src/gallium/auxiliary/llvm/storage.h delete mode 100644 src/gallium/auxiliary/llvm/storagesoa.cpp delete mode 100644 src/gallium/auxiliary/llvm/storagesoa.h delete mode 100644 src/gallium/auxiliary/llvm/tgsitollvm.cpp delete mode 100644 src/gallium/auxiliary/llvm/tgsitollvm.h (limited to 'src') diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile new file mode 100644 index 0000000000..39fac6ea4a --- /dev/null +++ b/src/gallium/auxiliary/gallivm/Makefile @@ -0,0 +1,85 @@ +# -*-makefile-*- +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = gallivm + + +GALLIVM_SOURCES = \ + gallivm.cpp \ + gallivm_cpu.cpp \ + instructions.cpp \ + loweringpass.cpp \ + tgsitollvm.cpp \ + storage.cpp \ + storagesoa.cpp \ + instructionssoa.cpp + +INC_SOURCES = gallivm_builtins.cpp + +CPP_SOURCES = \ + $(GALLIVM_SOURCES) + +C_SOURCES = +ASM_SOURCES = + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(CPP_SOURCES:.cpp=.o) \ + $(ASM_SOURCES:.S=.o) + +### Include directories +INCLUDES = \ + -I. \ + -I$(TOP)/src/gallium/drivers \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.cpp.o: + $(CXX) -c $(INCLUDES) $(LLVM_CXXFLAGS) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +##### TARGETS ##### + +default:: depend symlinks $(LIBNAME) + + +$(LIBNAME): $(OBJECTS) Makefile + $(TOP)/bin/mklib -o $@ -static $(OBJECTS) + + +depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) + rm -f depend + touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ + $(ASM_SOURCES) $(INC_SOURCES) 2> /dev/null + + +gallivm_builtins.cpp: llvm_builtins.c + clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o + -rm -f depend depend.bak + -rm -f gallivm_builtins.cpp + +symlinks: + + +include depend diff --git a/src/gallium/auxiliary/gallivm/gallivm.cpp b/src/gallium/auxiliary/gallivm/gallivm.cpp new file mode 100644 index 0000000000..d14bb3b99a --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm.cpp @@ -0,0 +1,327 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "instructions.h" +#include "loweringpass.h" +#include "storage.h" +#include "tgsitollvm.h" + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static int GLOBAL_ID = 0; + +using namespace llvm; + +static inline +void AddStandardCompilePasses(PassManager &PM) +{ + PM.add(new LoweringPass()); + PM.add(createVerifierPass()); // Verify that input is correct + + PM.add(createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp + + //PM.add(createStripSymbolsPass(true)); + + PM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst + PM.add(createCFGSimplificationPass()); // Clean up disgusting code + PM.add(createPromoteMemoryToRegisterPass());// Kill useless allocas + PM.add(createGlobalOptimizerPass()); // Optimize out global vars + PM.add(createGlobalDCEPass()); // Remove unused fns and globs + PM.add(createIPConstantPropagationPass());// IP Constant Propagation + PM.add(createDeadArgEliminationPass()); // Dead argument elimination + PM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE + PM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE + + PM.add(createPruneEHPass()); // Remove dead EH info + + PM.add(createFunctionInliningPass()); // Inline small functions + PM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args + + PM.add(createTailDuplicationPass()); // Simplify cfg by copying code + PM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas + PM.add(createInstructionCombiningPass()); // Combine silly seq's + PM.add(createCondPropagationPass()); // Propagate conditionals + + PM.add(createTailCallEliminationPass()); // Eliminate tail calls + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createReassociatePass()); // Reassociate expressions + PM.add(createLoopRotatePass()); + PM.add(createLICMPass()); // Hoist loop invariants + PM.add(createLoopUnswitchPass()); // Unswitch loops. + PM.add(createLoopIndexSplitPass()); // Index split loops. + PM.add(createInstructionCombiningPass()); // Clean up after LICM/reassoc + PM.add(createIndVarSimplifyPass()); // Canonicalize indvars + PM.add(createLoopUnrollPass()); // Unroll small loops + PM.add(createInstructionCombiningPass()); // Clean up after the unroller + PM.add(createGVNPass()); // Remove redundancies + PM.add(createSCCPPass()); // Constant prop with SCCP + + // Run instcombine after redundancy elimination to exploit opportunities + // opened up by them. + PM.add(createInstructionCombiningPass()); + PM.add(createCondPropagationPass()); // Propagate conditionals + + PM.add(createDeadStoreEliminationPass()); // Delete dead stores + PM.add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' + PM.add(createCFGSimplificationPass()); // Merge & remove BBs + PM.add(createSimplifyLibCallsPass()); // Library Call Optimizations + PM.add(createDeadTypeEliminationPass()); // Eliminate dead types + PM.add(createConstantMergePass()); // Merge dup global constants +} + +void gallivm_prog_delete(struct gallivm_prog *prog) +{ + delete prog->module; + prog->module = 0; + prog->function = 0; + free(prog); +} + +static inline void +constant_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan) +{ + unsigned i; + + for (i = 0; i < QUAD_SIZE; ++i) { + inputs[i][attrib][chan] = coefs[attrib].a0[chan]; + } +} + +static inline void +linear_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = inputs[i][0][0]; + const float y = inputs[i][0][1]; + + inputs[i][attrib][chan] = + coefs[attrib].a0[chan] + + coefs[attrib].dadx[chan] * x + + coefs[attrib].dady[chan] * y; + } +} + +static inline void +perspective_interpolation(float (*inputs)[16][4], + const struct tgsi_interp_coef *coefs, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = inputs[i][0][0]; + const float y = inputs[i][0][1]; + /* WPOS.w here is really 1/w */ + const float w = 1.0f / inputs[i][0][3]; + assert(inputs[i][0][3] != 0.0); + + inputs[i][attrib][chan] = + (coefs[attrib].a0[chan] + + coefs[attrib].dadx[chan] * x + + coefs[attrib].dady[chan] * y) * w; + } +} + +void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix) +{ + if (!ir || !ir->module) + return; + + if (file_prefix) { + std::ostringstream stream; + stream << file_prefix; + stream << ir->id; + stream << ".ll"; + std::string name = stream.str(); + std::ofstream out(name.c_str()); + if (!out) { + std::cerr<<"Can't open file : "<module); + out.close(); + } else { + const llvm::Module::FunctionListType &funcs = ir->module->getFunctionList(); + llvm::Module::FunctionListType::const_iterator itr; + std::cout<<"; ---------- Start shader "<id<id<num_interp; ++i) { + const gallivm_interpolate &interp = prog->interpolators[i]; + switch (interp.type) { + case TGSI_INTERPOLATE_CONSTANT: + constant_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + case TGSI_INTERPOLATE_LINEAR: + linear_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + case TGSI_INTERPOLATE_PERSPECTIVE: + perspective_interpolation(inputs, coef, interp.attrib, interp.chan); + break; + + default: + assert( 0 ); + } + } +} + + +struct gallivm_ir * gallivm_ir_new(enum gallivm_shader_type type) +{ + struct gallivm_ir *ir = + (struct gallivm_ir *)calloc(1, sizeof(struct gallivm_ir)); + ++GLOBAL_ID; + ir->id = GLOBAL_ID; + ir->type = type; + + return ir; +} + +void gallivm_ir_set_layout(struct gallivm_ir *ir, + enum gallivm_vector_layout layout) +{ + ir->layout = layout; +} + +void gallivm_ir_set_components(struct gallivm_ir *ir, int num) +{ + ir->num_components = num; +} + +void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, + const struct tgsi_token *tokens) +{ + std::cout << "Creating llvm from: " <module = mod; + gallivm_ir_dump(ir, 0); +} + +void gallivm_ir_delete(struct gallivm_ir *ir) +{ + delete ir->module; + free(ir); +} + +struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) +{ + struct gallivm_prog *prog = + (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); + llvm::Module *mod = llvm::CloneModule(ir->module); + prog->num_consts = ir->num_consts; + memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); + prog->num_interp = ir->num_interp; + + /* Run optimization passes over it */ + PassManager passes; + passes.add(new TargetData(mod)); + AddStandardCompilePasses(passes); + passes.run(*mod); + prog->module = mod; + + std::cout << "After optimizations:"<dump(); + + return prog; +} + +#endif /* MESA_LLVM */ diff --git a/src/gallium/auxiliary/gallivm/gallivm.h b/src/gallium/auxiliary/gallivm/gallivm.h new file mode 100644 index 0000000000..92da4bca7f --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm.h @@ -0,0 +1,103 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef GALLIVM_H +#define GALLIVM_H + +#if defined __cplusplus +extern "C" { +#endif + +#include "pipe/p_state.h" + +#ifdef MESA_LLVM + +struct tgsi_token; + +struct gallivm_ir; +struct gallivm_prog; +struct gallivm_cpu_engine; +struct tgsi_interp_coef; +struct tgsi_sampler; +struct tgsi_exec_vector; + +enum gallivm_shader_type { + GALLIVM_VS, + GALLIVM_FS +}; + +enum gallivm_vector_layout { + GALLIVM_AOS, + GALLIVM_SOA +}; + +struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type); +void gallivm_ir_set_layout(struct gallivm_ir *ir, + enum gallivm_vector_layout layout); +void gallivm_ir_set_components(struct gallivm_ir *ir, int num); +void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, + const struct tgsi_token *tokens); +void gallivm_ir_delete(struct gallivm_ir *ir); + + +struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir); + +void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, + float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], + const struct tgsi_interp_coef *coefs); +void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); + + +struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); +struct gallivm_cpu_engine *gallivm_global_cpu_engine(); +int gallivm_cpu_vs_exec(struct gallivm_prog *prog, + struct tgsi_exec_vector *inputs, + struct tgsi_exec_vector *dests, + float (*consts)[4], + struct tgsi_exec_vector *temps); +int gallivm_cpu_fs_exec(struct gallivm_prog *prog, + float x, float y, + float (*dests)[PIPE_MAX_SHADER_INPUTS][4], + float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], + float (*consts)[4], + struct tgsi_sampler *samplers); +void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); +void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); + + +#endif /* MESA_LLVM */ + +#if defined __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp new file mode 100644 index 0000000000..1796f0a177 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp @@ -0,0 +1,567 @@ +// Generated by llvm2cpp - DO NOT MODIFY! + + +Module* createGallivmBuiltins(Module *mod) { + +mod->setModuleIdentifier("shader"); + +// Type Definitions +ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); + +PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); + +std::vectorFuncTy_2_args; +FuncTy_2_args.push_back(Type::FloatTy); +FuncTy_2_args.push_back(Type::FloatTy); +FunctionType* FuncTy_2 = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/FuncTy_2_args, + /*isVarArg=*/false); + +PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); + +VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); + +std::vectorFuncTy_5_args; +FuncTy_5_args.push_back(VectorTy_4); +FunctionType* FuncTy_5 = FunctionType::get( + /*Result=*/VectorTy_4, + /*Params=*/FuncTy_5_args, + /*isVarArg=*/false); + +std::vectorFuncTy_6_args; +FuncTy_6_args.push_back(VectorTy_4); +FuncTy_6_args.push_back(VectorTy_4); +FuncTy_6_args.push_back(VectorTy_4); +FunctionType* FuncTy_6 = FunctionType::get( + /*Result=*/VectorTy_4, + /*Params=*/FuncTy_6_args, + /*isVarArg=*/false); + +VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); + +std::vectorFuncTy_9_args; +FunctionType* FuncTy_9 = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/FuncTy_9_args, + /*isVarArg=*/true); + +PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); + +PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); + +std::vectorFuncTy_12_args; +FuncTy_12_args.push_back(Type::FloatTy); +FunctionType* FuncTy_12 = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/FuncTy_12_args, + /*isVarArg=*/false); + +PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); + +std::vectorFuncTy_13_args; +FuncTy_13_args.push_back(VectorTy_4); +FunctionType* FuncTy_13 = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/FuncTy_13_args, + /*isVarArg=*/false); + + +// Function Declarations + +Function* func_approx = new Function( + /*Type=*/FuncTy_2, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"approx", mod); +func_approx->setCallingConv(CallingConv::C); +const ParamAttrsList *func_approx_PAL = 0; +func_approx->setParamAttrs(func_approx_PAL); + +Function* func_powf = new Function( + /*Type=*/FuncTy_2, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"powf", mod); // (external, no body) +func_powf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_powf_PAL = 0; +func_powf->setParamAttrs(func_powf_PAL); + +Function* func_lit = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"lit", mod); +func_lit->setCallingConv(CallingConv::C); +const ParamAttrsList *func_lit_PAL = 0; +func_lit->setParamAttrs(func_lit_PAL); + +Function* func_cmp = new Function( + /*Type=*/FuncTy_6, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"cmp", mod); +func_cmp->setCallingConv(CallingConv::C); +const ParamAttrsList *func_cmp_PAL = 0; +{ + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; + Attrs.push_back(PAWI); + func_cmp_PAL = ParamAttrsList::get(Attrs); + +} +func_cmp->setParamAttrs(func_cmp_PAL); + +Function* func_vcos = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"vcos", mod); +func_vcos->setCallingConv(CallingConv::C); +const ParamAttrsList *func_vcos_PAL = 0; +func_vcos->setParamAttrs(func_vcos_PAL); + +Function* func_printf = new Function( + /*Type=*/FuncTy_9, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"printf", mod); // (external, no body) +func_printf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_printf_PAL = 0; +func_printf->setParamAttrs(func_printf_PAL); + +Function* func_cosf = new Function( + /*Type=*/FuncTy_12, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"cosf", mod); // (external, no body) +func_cosf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_cosf_PAL = 0; +func_cosf->setParamAttrs(func_cosf_PAL); + +Function* func_scs = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"scs", mod); +func_scs->setCallingConv(CallingConv::C); +const ParamAttrsList *func_scs_PAL = 0; +func_scs->setParamAttrs(func_scs_PAL); + +Function* func_sinf = new Function( + /*Type=*/FuncTy_12, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"sinf", mod); // (external, no body) +func_sinf->setCallingConv(CallingConv::C); +const ParamAttrsList *func_sinf_PAL = 0; +func_sinf->setParamAttrs(func_sinf_PAL); + +Function* func_vsin = new Function( + /*Type=*/FuncTy_5, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"vsin", mod); +func_vsin->setCallingConv(CallingConv::C); +const ParamAttrsList *func_vsin_PAL = 0; +func_vsin->setParamAttrs(func_vsin_PAL); + +Function* func_kilp = new Function( + /*Type=*/FuncTy_13, + /*Linkage=*/GlobalValue::WeakLinkage, + /*Name=*/"kilp", mod); +func_kilp->setCallingConv(CallingConv::C); +const ParamAttrsList *func_kilp_PAL = 0; +{ + ParamAttrsVector Attrs; + ParamAttrsWithIndex PAWI; + PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; + Attrs.push_back(PAWI); + func_kilp_PAL = ParamAttrsList::get(Attrs); + +} +func_kilp->setParamAttrs(func_kilp_PAL); + +// Global Variable Declarations + + +GlobalVariable* gvar_array__str = new GlobalVariable( +/*Type=*/ArrayTy_0, +/*isConstant=*/true, +/*Linkage=*/GlobalValue::InternalLinkage, +/*Initializer=*/0, // has initializer, specified below +/*Name=*/".str", +mod); + +GlobalVariable* gvar_array__str1 = new GlobalVariable( +/*Type=*/ArrayTy_0, +/*isConstant=*/true, +/*Linkage=*/GlobalValue::InternalLinkage, +/*Initializer=*/0, // has initializer, specified below +/*Name=*/".str1", +mod); + +// Constant Definitions +Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); +Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); +ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); +ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); +Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); +Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); +std::vector const_packed_20_elems; +ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); +const_packed_20_elems.push_back(const_float_21); +UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); +const_packed_20_elems.push_back(const_float_22); +const_packed_20_elems.push_back(const_float_22); +const_packed_20_elems.push_back(const_float_21); +Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); +ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); +ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); +ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); +std::vector const_packed_26_elems; +const_packed_26_elems.push_back(const_float_21); +const_packed_26_elems.push_back(const_float_18); +const_packed_26_elems.push_back(const_float_18); +const_packed_26_elems.push_back(const_float_21); +Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); +Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); +std::vector const_packed_28_elems; +const_packed_28_elems.push_back(const_int32_19); +ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); +const_packed_28_elems.push_back(const_int32_29); +const_packed_28_elems.push_back(const_int32_25); +const_packed_28_elems.push_back(const_int32_24); +Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); +std::vector const_packed_30_elems; +const_packed_30_elems.push_back(const_int32_19); +const_packed_30_elems.push_back(const_int32_23); +ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); +const_packed_30_elems.push_back(const_int32_31); +const_packed_30_elems.push_back(const_int32_24); +Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); +std::vector const_packed_32_elems; +const_packed_32_elems.push_back(const_int32_19); +const_packed_32_elems.push_back(const_int32_23); +const_packed_32_elems.push_back(const_int32_25); +ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); +const_packed_32_elems.push_back(const_int32_33); +Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); +std::vector const_ptr_34_indices; +const_ptr_34_indices.push_back(const_int32_19); +const_ptr_34_indices.push_back(const_int32_19); +Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); +UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); +std::vector const_ptr_36_indices; +const_ptr_36_indices.push_back(const_int32_19); +const_ptr_36_indices.push_back(const_int32_19); +Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); + +// Global Variable Definitions +gvar_array__str->setInitializer(const_array_14); +gvar_array__str1->setInitializer(const_array_15); + +// Function Definitions + +// Function: approx (func_approx) +{ + Function::arg_iterator args = func_approx->arg_begin(); + Value* float_a = args++; + float_a->setName("a"); + Value* float_b = args++; + float_b->setName("b"); + + BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); + + // Block entry (label_entry) + FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); + SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); + FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); + SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); + FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); + SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); + std::vector float_call_params; + float_call_params.push_back(float_a_addr_0); + float_call_params.push_back(float_b_addr_1); + CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); + float_call->setCallingConv(CallingConv::C); + float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; + float_call->setParamAttrs(float_call_PAL); + + new ReturnInst(float_call, label_entry); + +} + +// Function: lit (func_lit) +{ + Function::arg_iterator args = func_lit->arg_begin(); + Value* packed_tmp = args++; + packed_tmp->setName("tmp"); + + BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); + BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); + BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); + + // Block entry (label_entry_38) + ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); + FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); + new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); + + // Block ifthen (label_ifthen) + InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); + ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); + ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); + std::vector float_call_41_params; + float_call_41_params.push_back(float_tmp12); + float_call_41_params.push_back(float_tmp14); + CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); + float_call_41->setCallingConv(CallingConv::C); + float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; + float_call_41->setParamAttrs(float_call_41_PAL); + + InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); + new ReturnInst(packed_tmp16, label_ifthen); + + // Block UnifiedReturnBlock (label_UnifiedReturnBlock) + new ReturnInst(const_packed_26, label_UnifiedReturnBlock); + +} + +// Function: cmp (func_cmp) +{ + Function::arg_iterator args = func_cmp->arg_begin(); + Value* packed_tmp0 = args++; + packed_tmp0->setName("tmp0"); + Value* packed_tmp1 = args++; + packed_tmp1->setName("tmp1"); + Value* packed_tmp2 = args++; + packed_tmp2->setName("tmp2"); + + BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); + BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); + BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); + BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); + BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); + BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); + BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); + + // Block entry (label_entry_44) + ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); + CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); + FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); + ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); + CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); + FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); + SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); + new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); + + // Block cond.?14 (label_cond__14) + ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); + ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); + CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); + FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); + new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); + + // Block cond.cont20 (label_cond_cont20) + ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); + ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); + CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); + FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); + new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); + + // Block cond.?28 (label_cond__28) + PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); + packed_tmp23_reg2mem_0->reserveOperandSpace(2); + packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); + packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); + + ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); + ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); + CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); + FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); + new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); + + // Block cond.cont34 (label_cond_cont34) + PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); + packed_tmp23_reg2mem_1->reserveOperandSpace(2); + packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); + packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); + + ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); + ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); + CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); + FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); + new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); + + // Block cond.?42 (label_cond__42) + PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); + packed_tmp37_reg2mem_0->reserveOperandSpace(2); + packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); + packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); + + ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); + new ReturnInst(packed_tmp5113, label_cond__42); + + // Block cond.cont48 (label_cond_cont48) + PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); + packed_tmp37_reg2mem_1->reserveOperandSpace(2); + packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); + packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); + + ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); + new ReturnInst(packed_tmp51, label_cond_cont48); + +} + +// Function: vcos (func_vcos) +{ + Function::arg_iterator args = func_vcos->arg_begin(); + Value* packed_val = args++; + packed_val->setName("val"); + + BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); + + // Block entry (label_entry_53) + ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); + CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); + ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); + CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); + ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); + CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); + ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); + CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); + std::vector int32_call_params; + int32_call_params.push_back(const_ptr_34); + int32_call_params.push_back(double_conv_54); + int32_call_params.push_back(double_conv4); + int32_call_params.push_back(double_conv7); + int32_call_params.push_back(double_conv10); + CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); + int32_call->setCallingConv(CallingConv::C); + int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; + int32_call->setParamAttrs(int32_call_PAL); + + CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); + float_call13->setCallingConv(CallingConv::C); + float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; + float_call13->setParamAttrs(float_call13_PAL); + + InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); + CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); + float_call18->setCallingConv(CallingConv::C); + float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; + float_call18->setParamAttrs(float_call18_PAL); + + InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); + CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); + float_call23->setCallingConv(CallingConv::C); + float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; + float_call23->setParamAttrs(float_call23_PAL); + + InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); + CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); + float_call28->setCallingConv(CallingConv::C); + float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; + float_call28->setParamAttrs(float_call28_PAL); + + InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); + CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); + CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); + CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); + CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); + std::vector int32_call43_params; + int32_call43_params.push_back(const_ptr_36); + int32_call43_params.push_back(double_conv33); + int32_call43_params.push_back(double_conv36); + int32_call43_params.push_back(double_conv39); + int32_call43_params.push_back(double_conv42); + CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); + int32_call43->setCallingConv(CallingConv::C); + int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; + int32_call43->setParamAttrs(int32_call43_PAL); + + new ReturnInst(packed_tmp30, label_entry_53); + +} + +// Function: scs (func_scs) +{ + Function::arg_iterator args = func_scs->arg_begin(); + Value* packed_val_58 = args++; + packed_val_58->setName("val"); + + BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); + + // Block entry (label_entry_59) + ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); + CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); + float_call_60->setCallingConv(CallingConv::C); + float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; + float_call_60->setParamAttrs(float_call_60_PAL); + + InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); + CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); + float_call7->setCallingConv(CallingConv::C); + float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; + float_call7->setParamAttrs(float_call7_PAL); + + InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); + new ReturnInst(packed_tmp9, label_entry_59); + +} + +// Function: vsin (func_vsin) +{ + Function::arg_iterator args = func_vsin->arg_begin(); + Value* packed_val_62 = args++; + packed_val_62->setName("val"); + + BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); + + // Block entry (label_entry_63) + ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); + CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); + float_call_65->setCallingConv(CallingConv::C); + float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; + float_call_65->setParamAttrs(float_call_65_PAL); + + InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); + InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); + InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); + InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); + new ReturnInst(packed_tmp15_67, label_entry_63); + +} + +// Function: kilp (func_kilp) +{ + Function::arg_iterator args = func_kilp->arg_begin(); + Value* packed_val_69 = args++; + packed_val_69->setName("val"); + + BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); + BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); + BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); + BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); + BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); + + // Block entry (label_entry_70) + ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); + FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); + + // Block lor_rhs (label_lor_rhs) + ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); + FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); + + // Block lor_rhs5 (label_lor_rhs5) + ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); + FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); + new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); + + // Block lor_rhs11 (label_lor_rhs11) + ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); + FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); + CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); + new ReturnInst(int32_retval, label_lor_rhs11); + + // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) + new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); + +} + +return mod; + +} diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp new file mode 100644 index 0000000000..8f9830d0b1 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp @@ -0,0 +1,202 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "instructions.h" +#include "loweringpass.h" +#include "storage.h" +#include "tgsitollvm.h" + +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_dump.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct gallivm_cpu_engine { + llvm::ExecutionEngine *engine; +}; + +static struct gallivm_cpu_engine *CPU = 0; + +typedef int (*fragment_shader_runner)(float x, float y, + float (*dests)[16][4], + float (*inputs)[16][4], + int num_attribs, + float (*consts)[4], int num_consts, + struct tgsi_sampler *samplers); + +int gallivm_cpu_fs_exec(struct gallivm_prog *prog, + float fx, float fy, + float (*dests)[16][4], + float (*inputs)[16][4], + float (*consts)[4], + struct tgsi_sampler *samplers) +{ + fragment_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); + + return runner(fx, fy, dests, inputs, prog->num_interp, + consts, prog->num_consts, + samplers); +} + +static inline llvm::Function *func_for_shader(struct gallivm_prog *prog) +{ + llvm::Module *mod = prog->module; + llvm::Function *func = 0; + + switch (prog->type) { + case GALLIVM_VS: + func = mod->getFunction("vs_shader"); + break; + case GALLIVM_FS: + func = mod->getFunction("fs_shader"); + break; + default: + assert(!"Unknown shader type!"); + break; + } + return func; +} + +/*! + This function creates a CPU based execution engine for the given gallivm_prog. + gallivm_cpu_engine should be used as a singleton throughout the library. Before + executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile. + The gallivm_prog instance which is being passed to the constructor is being + automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile + with it again. + */ +struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) +{ + struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *) + calloc(1, sizeof(struct gallivm_cpu_engine)); + llvm::Module *mod = static_cast(prog->module); + llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); + llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false); + ee->DisableLazyCompilation(); + cpu->engine = ee; + + llvm::Function *func = func_for_shader(prog); + + prog->function = ee->getPointerToFunction(func); + CPU = cpu; + return cpu; +} + + +/*! + This function JIT compiles the given gallivm_prog with the given cpu based execution engine. + The reference to the generated machine code entry point will be stored + in the gallivm_prog program. After executing this function one can call gallivm_prog_exec + in order to execute the gallivm_prog on the CPU. + */ +void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog) +{ + llvm::Module *mod = static_cast(prog->module); + llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); + llvm::ExecutionEngine *ee = cpu->engine; + assert(ee); + /*FIXME : remove */ + ee->DisableLazyCompilation(); + ee->addModuleProvider(mp); + + llvm::Function *func = func_for_shader(prog); + prog->function = ee->getPointerToFunction(func); +} + +void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) +{ + free(cpu); +} + +struct gallivm_cpu_engine * gallivm_global_cpu_engine() +{ + return CPU; +} + + +typedef void (*vertex_shader_runner)(void *ainputs, + void *dests, + float (*aconsts)[4], + void *temps); + + +/*! + This function is used to execute the gallivm_prog in software. Before calling + this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile + function. + */ +int gallivm_cpu_vs_exec(struct gallivm_prog *prog, + struct tgsi_exec_vector *inputs, + struct tgsi_exec_vector *dests, + float (*consts)[4], + struct tgsi_exec_vector *temps) +{ + vertex_shader_runner runner = reinterpret_cast(prog->function); + assert(runner); + /*FIXME*/ + runner(inputs, dests, consts, temps); + + return 0; +} + +#endif diff --git a/src/gallium/auxiliary/gallivm/gallivm_p.h b/src/gallium/auxiliary/gallivm/gallivm_p.h new file mode 100644 index 0000000000..cfe7b1901b --- /dev/null +++ b/src/gallium/auxiliary/gallivm/gallivm_p.h @@ -0,0 +1,110 @@ +#ifndef GALLIVM_P_H +#define GALLIVM_P_H + +#ifdef MESA_LLVM + +#include "gallivm.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_compiler.h" + +namespace llvm { + class Module; +} + +#if defined __cplusplus +extern "C" { +#endif + +enum gallivm_shader_type; +enum gallivm_vector_layout; + +struct gallivm_interpolate { + int attrib; + int chan; + int type; +}; + +struct gallivm_ir { + llvm::Module *module; + int id; + enum gallivm_shader_type type; + enum gallivm_vector_layout layout; + int num_components; + int num_consts; + + //FIXME: this might not be enough for some shaders + struct gallivm_interpolate interpolators[32*4]; + int num_interp; +}; + +struct gallivm_prog { + llvm::Module *module; + void *function; + + int id; + enum gallivm_shader_type type; + + int num_consts; + + //FIXME: this might not be enough for some shaders + struct gallivm_interpolate interpolators[32*4]; + int num_interp; +}; + +static INLINE void gallivm_swizzle_components(int swizzle, + int *xc, int *yc, + int *zc, int *wc) +{ + int x = swizzle / 1000; swizzle -= x * 1000; + int y = swizzle / 100; swizzle -= y * 100; + int z = swizzle / 10; swizzle -= z * 10; + int w = swizzle; + + if (xc) *xc = x; + if (yc) *yc = y; + if (zc) *zc = z; + if (wc) *wc = w; +} + +static INLINE boolean gallivm_is_swizzle(int swizzle) +{ + const int NO_SWIZZLE = TGSI_SWIZZLE_X * 1000 + TGSI_SWIZZLE_Y * 100 + + TGSI_SWIZZLE_Z * 10 + TGSI_SWIZZLE_W; + return swizzle != NO_SWIZZLE; +} + +static INLINE int gallivm_x_swizzle(int swizzle) +{ + int x; + gallivm_swizzle_components(swizzle, &x, 0, 0, 0); + return x; +} + +static INLINE int gallivm_y_swizzle(int swizzle) +{ + int y; + gallivm_swizzle_components(swizzle, 0, &y, 0, 0); + return y; +} + +static INLINE int gallivm_z_swizzle(int swizzle) +{ + int z; + gallivm_swizzle_components(swizzle, 0, 0, &z, 0); + return z; +} + +static INLINE int gallivm_w_swizzle(int swizzle) +{ + int w; + gallivm_swizzle_components(swizzle, 0, 0, 0, &w); + return w; +} + +#endif /* MESA_LLVM */ + +#if defined __cplusplus +} // extern "C" +#endif + +#endif diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp new file mode 100644 index 0000000000..55d39fa5f1 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -0,0 +1,889 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "instructions.h" + +#include "storage.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace llvm; + +#include "gallivm_builtins.cpp" + +static inline std::string createFuncName(int label) +{ + std::ostringstream stream; + stream << "function"; + stream << label; + return stream.str(); +} + +Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, + Storage *storage) + : m_mod(mod), m_func(func), m_builder(block), m_idx(0), + m_storage(storage) +{ + m_floatVecType = VectorType::get(Type::FloatTy, 4); + + m_llvmFSqrt = 0; + m_llvmFAbs = 0; + m_llvmPow = 0; + m_llvmFloor = 0; + m_llvmFlog = 0; + m_llvmLit = 0; + m_fmtPtr = 0; + + createGallivmBuiltins(m_mod); +} + +llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) +{ + return m_builder.CreateAdd(in1, in2, name("add")); +} + +llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + Value *mulRes = mul(in1, in2); + return add(mulRes, in3); +} + +llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) +{ + return m_builder.CreateMul(in1, in2, name("mul")); +} + +const char * Instructions::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + Value *x = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(0), + name("extractx")); + Value *y = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(1), + name("extracty")); + Value *z = m_builder.CreateExtractElement(mulRes, + m_storage->constantInt(2), + name("extractz")); + Value *xy = m_builder.CreateAdd(x, y,name("xy")); + Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3")); + return vectorFromVals(dot3, dot3, dot3, dot3); +} + +llvm::Value *Instructions::callFSqrt(llvm::Value *val) +{ + if (!m_llvmFSqrt) { + // predeclare the intrinsic + std::vector fsqrtArgs; + fsqrtArgs.push_back(Type::FloatTy); + ParamAttrsList *fsqrtPal = 0; + FunctionType* fsqrtType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fsqrtArgs, + /*isVarArg=*/false); + m_llvmFSqrt = new Function( + /*Type=*/fsqrtType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.sqrt.f32", m_mod); + m_llvmFSqrt->setCallingConv(CallingConv::C); + m_llvmFSqrt->setParamAttrs(fsqrtPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val, + name("sqrt")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::rsq(llvm::Value *in1) +{ + Value *x = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("extractx")); + Value *abs = callFAbs(x); + Value *sqrt = callFSqrt(abs); + + Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + sqrt, + name("rsqrt")); + return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); +} + +llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + Constant *const_vec = Constant::getNullValue(m_floatVecType); + Value *res = m_builder.CreateInsertElement(const_vec, x, + m_storage->constantInt(0), + name("vecx")); + res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), + name("vecxy")); + res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), + name("vecxyz")); + if (w) + res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), + name("vecxyzw")); + return res; +} + +llvm::Value *Instructions::callFAbs(llvm::Value *val) +{ + if (!m_llvmFAbs) { + // predeclare the intrinsic + std::vector fabsArgs; + fabsArgs.push_back(Type::FloatTy); + ParamAttrsList *fabsPal = 0; + FunctionType* fabsType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/fabsArgs, + /*isVarArg=*/false); + m_llvmFAbs = new Function( + /*Type=*/fabsType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"fabs", m_mod); + m_llvmFAbs->setCallingConv(CallingConv::C); + m_llvmFAbs->setParamAttrs(fabsPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFAbs, val, + name("fabs")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lit(llvm::Value *in) +{ + if (!m_llvmLit) { + m_llvmLit = m_mod->getFunction("lit"); + } + CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2) +{ + Value *res = m_builder.CreateSub(in1, in2, name("sub")); + return res; +} + +llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) +{ + if (!m_llvmPow) { + // predeclare the intrinsic + std::vector powArgs; + powArgs.push_back(Type::FloatTy); + powArgs.push_back(Type::FloatTy); + ParamAttrsList *powPal = 0; + FunctionType* powType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/powArgs, + /*isVarArg=*/false); + m_llvmPow = new Function( + /*Type=*/powType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"llvm.pow.f32", m_mod); + m_llvmPow->setCallingConv(CallingConv::C); + m_llvmPow->setParamAttrs(powPal); + } + std::vector params; + params.push_back(val1); + params.push_back(val2); + CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(), + name("pow")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *x2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(0), + name("x2")); + llvm::Value *val = callPow(x1, x2); + return vectorFromVals(val, val, val, val); +} + +llvm::Value * Instructions::rcp(llvm::Value *in1) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, + APFloat(1.f)), + x1, name("rcp")); + return vectorFromVals(res, res, res, res); +} + +llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + std::vector vec = extractVector(mulRes); + Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy")); + Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz")); + Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4")); + return vectorFromVals(dot4, dot4, dot4, dot4); +} + +llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2) +{ + Value *mulRes = mul(in1, in2); + std::vector vec1 = extractVector(mulRes); + Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy")); + Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz")); + Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph")); + return vectorFromVals(dph, dph, dph, dph); +} + +llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) +{ + Value *y1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(1), + name("y1")); + Value *z = m_builder.CreateExtractElement(in1, + m_storage->constantInt(2), + name("z")); + Value *y2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(1), + name("y2")); + Value *w = m_builder.CreateExtractElement(in2, + m_storage->constantInt(3), + name("w")); + Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); + return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)), + ry, z, w); +} + +llvm::Value * Instructions::ex2(llvm::Value *in) +{ + llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)), + m_builder.CreateExtractElement( + in, m_storage->constantInt(0), + name("x1"))); + return vectorFromVals(val, val, val, val); +} + +llvm::Value * Instructions::callFloor(llvm::Value *val) +{ + if (!m_llvmFloor) { + // predeclare the intrinsic + std::vector floorArgs; + floorArgs.push_back(Type::FloatTy); + ParamAttrsList *floorPal = 0; + FunctionType* floorType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/floorArgs, + /*isVarArg=*/false); + m_llvmFloor = new Function( + /*Type=*/floorType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"floorf", m_mod); + m_llvmFloor->setCallingConv(CallingConv::C); + m_llvmFloor->setParamAttrs(floorPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFloor, val, + name("floorf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::floor(llvm::Value *in) +{ + std::vector vec = extractVector(in); + return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]), + callFloor(vec[2]), callFloor(vec[3])); +} + +llvm::Value * Instructions::arl(llvm::Value *in) +{ + return floor(in); +} + +llvm::Value * Instructions::frc(llvm::Value *in) +{ + llvm::Value *flr = floor(in); + return sub(in, flr); +} + +llvm::Value * Instructions::callFLog(llvm::Value *val) +{ + if (!m_llvmFlog) { + // predeclare the intrinsic + std::vector flogArgs; + flogArgs.push_back(Type::FloatTy); + ParamAttrsList *flogPal = 0; + FunctionType* flogType = FunctionType::get( + /*Result=*/Type::FloatTy, + /*Params=*/flogArgs, + /*isVarArg=*/false); + m_llvmFlog = new Function( + /*Type=*/flogType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"logf", m_mod); + m_llvmFlog->setCallingConv(CallingConv::C); + m_llvmFlog->setParamAttrs(flogPal); + } + CallInst *call = m_builder.CreateCall(m_llvmFlog, val, + name("logf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::lg2(llvm::Value *in) +{ + std::vector vec = extractVector(in); + llvm::Value *const_vec = constVector(1.442695f, 1.442695f, + 1.442695f, 1.442695f); + return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), + callFLog(vec[2]), callFLog(vec[3])), const_vec); +} + +llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2) +{ + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); + Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], + name("selx")); + + Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); + Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], + name("sely")); + + Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); + Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], + name("selz")); + + Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); + Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], + name("selw")); + + return vectorFromVals(selx, sely, selz, selw); +} + +llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2) +{ + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], + name("xcmp")); + Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], + name("selx")); + + Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], + name("ycmp")); + Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], + name("sely")); + + Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], + name("zcmp")); + Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], + name("selz")); + + Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], + name("wcmp")); + Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], + name("selw")); + + return vectorFromVals(selx, sely, selz, selw); +} + +void Instructions::printVector(llvm::Value *val) +{ + static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A"; + + if (!m_fmtPtr) { + Constant *format = ConstantArray::get(frmt, true); + ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1); + GlobalVariable* globalFormat = new GlobalVariable( + /*Type=*/arrayTy, + /*isConstant=*/true, + /*Linkage=*/GlobalValue::InternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name(".str"), + m_mod); + globalFormat->setInitializer(format); + + Constant* const_int0 = Constant::getNullValue(IntegerType::get(32)); + std::vector const_ptr_21_indices; + const_ptr_21_indices.push_back(const_int0); + const_ptr_21_indices.push_back(const_int0); + m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat, + &const_ptr_21_indices[0], const_ptr_21_indices.size()); + } + + Function *func_printf = m_mod->getFunction("printf"); + if (!func_printf) + func_printf = declarePrintf(); + assert(func_printf); + std::vector vec = extractVector(val); + Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx")); + Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy")); + Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz")); + Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw")); + std::vector params; + params.push_back(m_fmtPtr); + params.push_back(dx); + params.push_back(dy); + params.push_back(dz); + params.push_back(dw); + CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(), + name("printf")); + call->setCallingConv(CallingConv::C); + call->setTailCall(true); +} + +llvm::Function * Instructions::declarePrintf() +{ + std::vector args; + ParamAttrsList *params = 0; + FunctionType* funcTy = FunctionType::get( + /*Result=*/IntegerType::get(32), + /*Params=*/args, + /*isVarArg=*/true); + Function* func_printf = new Function( + /*Type=*/funcTy, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/"printf", m_mod); + func_printf->setCallingConv(CallingConv::C); + func_printf->setParamAttrs(params); + return func_printf; +} + + +llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} +llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} + + +llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) +{ + Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); + Constant *const0f = Constant::getNullValue(Type::FloatTy); + + std::vector vec1 = extractVector(in1); + std::vector vec2 = extractVector(in2); + + Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); + Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); + + Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); + Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); + + Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); + Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); + + Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); + Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); + + return vectorFromVals(x, y, z, w); +} + +llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) +{ + Value *x1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(0), + name("x1")); + Value *y1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(1), + name("y1")); + Value *z1 = m_builder.CreateExtractElement(in1, + m_storage->constantInt(2), + name("z1")); + + Value *x2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(0), + name("x2")); + Value *y2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(1), + name("y2")); + Value *z2 = m_builder.CreateExtractElement(in2, + m_storage->constantInt(2), + name("z2")); + Value *y1z2 = mul(y1, z2); + Value *z1y2 = mul(z1, y2); + + Value *z1x2 = mul(z1, x2); + Value *x1z2 = mul(x1, z2); + + Value *x1y2 = mul(x1, y2); + Value *y1x2 = mul(y1, x2); + + return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2)); +} + + +llvm::Value * Instructions::abs(llvm::Value *in) +{ + std::vector vec = extractVector(in); + Value *xabs = callFAbs(vec[0]); + Value *yabs = callFAbs(vec[1]); + Value *zabs = callFAbs(vec[2]); + Value *wabs = callFAbs(vec[3]); + return vectorFromVals(xabs, yabs, zabs, wabs); +} + +void Instructions::ifop(llvm::Value *in) +{ + BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); + BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); + + //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); + //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); + //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0); + + Constant *float0 = Constant::getNullValue(Type::FloatTy); + + Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0), + name("extractx")); + Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp")); + m_builder.CreateCondBr(xcmp, ifthen, ifend); + //m_builder.SetInsertPoint(yblock); + + m_builder.SetInsertPoint(ifthen); + m_ifStack.push(ifend); +} + +llvm::BasicBlock * Instructions::currentBlock() const +{ + return m_builder.GetInsertBlock(); +} + +void Instructions::elseop() +{ + assert(!m_ifStack.empty()); + BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); + m_builder.CreateBr(ifend); + m_builder.SetInsertPoint(m_ifStack.top()); + currentBlock()->setName(name("ifelse")); + m_ifStack.pop(); + m_ifStack.push(ifend); +} + +void Instructions::endif() +{ + assert(!m_ifStack.empty()); + m_builder.CreateBr(m_ifStack.top()); + m_builder.SetInsertPoint(m_ifStack.top()); + m_ifStack.pop(); +} + +llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3) +{ + llvm::Value *m = mul(in1, in2); + llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f); + llvm::Value *s = sub(vec1, in1); + return add(m, mul(s, in3)); +} + +void Instructions::beginLoop() +{ + BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); + BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); + + m_builder.CreateBr(begin); + Loop loop; + loop.begin = begin; + loop.end = end; + m_builder.SetInsertPoint(begin); + m_loopStack.push(loop); +} + +void Instructions::endLoop() +{ + assert(!m_loopStack.empty()); + Loop loop = m_loopStack.top(); + m_builder.CreateBr(loop.begin); + loop.end->moveAfter(currentBlock()); + m_builder.SetInsertPoint(loop.end); + m_loopStack.pop(); +} + +void Instructions::brk() +{ + assert(!m_loopStack.empty()); + BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); + m_builder.CreateBr(m_loopStack.top().end); + m_builder.SetInsertPoint(unr); +} + +llvm::Value * Instructions::trunc(llvm::Value *in) +{ + std::vector vec = extractVector(in); + Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32), + name("ftoix")); + Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32), + name("ftoiy")); + Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32), + name("ftoiz")); + Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32), + name("ftoiw")); + Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy, + name("fx")); + Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy, + name("fy")); + Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy, + name("fz")); + Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy, + name("fw")); + return vectorFromVals(fx, fy, fz, fw); +} + +void Instructions::end() +{ + m_builder.CreateRetVoid(); +} + +void Instructions::cal(int label, llvm::Value *input) +{ + std::vector params; + params.push_back(input); + llvm::Function *func = findFunction(label); + + m_builder.CreateCall(func, params.begin(), params.end()); +} + +llvm::Function * Instructions::declareFunc(int label) +{ + PointerType *vecPtr = PointerType::getUnqual(m_floatVecType); + std::vector args; + args.push_back(vecPtr); + args.push_back(vecPtr); + args.push_back(vecPtr); + args.push_back(vecPtr); + ParamAttrsList *params = 0; + FunctionType *funcType = FunctionType::get( + /*Result=*/Type::VoidTy, + /*Params=*/args, + /*isVarArg=*/false); + std::string name = createFuncName(label); + Function *func = new Function( + /*Type=*/funcType, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Name=*/name.c_str(), m_mod); + func->setCallingConv(CallingConv::C); + func->setParamAttrs(params); + return func; +} + +void Instructions::bgnSub(unsigned label) +{ + llvm::Function *func = findFunction(label); + + Function::arg_iterator args = func->arg_begin(); + Value *ptr_INPUT = args++; + ptr_INPUT->setName("INPUT"); + m_storage->pushArguments(ptr_INPUT); + + llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); + + m_func = func; + m_builder.SetInsertPoint(entry); +} + +void Instructions::endSub() +{ + m_func = 0; + m_builder.SetInsertPoint(0); +} + +llvm::Function * Instructions::findFunction(int label) +{ + llvm::Function *func = m_functions[label]; + if (!func) { + func = declareFunc(label); + m_functions[label] = func; + } + return func; +} + +llvm::Value * Instructions::constVector(float x, float y, float z, float w) +{ + std::vector vec(4); + vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x)); + vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y)); + vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z)); + vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w)); + return ConstantVector::get(m_floatVecType, vec); +} + + +std::vector Instructions::extractVector(llvm::Value *vec) +{ + std::vector elems(4); + elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0), + name("x")); + elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1), + name("y")); + elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2), + name("z")); + elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3), + name("w")); + return elems; +} + +llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) +{ + llvm::Function *func = m_mod->getFunction("cmp"); + assert(func); + + std::vector params; + params.push_back(in1); + params.push_back(in2); + params.push_back(in3); + CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::cos(llvm::Value *in) +{ +#if 0 + llvm::Function *func = m_mod->getFunction("vcos"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("cosres")); + call->setTailCall(false); + return call; +#else + std::vector elems = extractVector(in); + Function *func = m_mod->getFunction("cosf"); + assert(func); + CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres")); + cos->setCallingConv(CallingConv::C); + cos->setTailCall(true); + return vectorFromVals(cos, cos, cos, cos); +#endif +} + +llvm::Value * Instructions::scs(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("scs"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("scsres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::kilp(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("kilp"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); + call->setTailCall(false); + return call; +} + +llvm::Value * Instructions::sin(llvm::Value *in) +{ + llvm::Function *func = m_mod->getFunction("vsin"); + assert(func); + + CallInst *call = m_builder.CreateCall(func, in, name("sinres")); + call->setTailCall(false); + return call; +} +#endif //MESA_LLVM + + diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h new file mode 100644 index 0000000000..9ebc17dd8e --- /dev/null +++ b/src/gallium/auxiliary/gallivm/instructions.h @@ -0,0 +1,152 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef INSTRUCTIONS_H +#define INSTRUCTIONS_H + +#include +#include +#include +#include + +#include +#include + +namespace llvm { + class VectorType; + class Function; +} + +class Storage; + +class Instructions +{ +public: + Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, + Storage *storage); + + llvm::BasicBlock *currentBlock() const; + + llvm::Value *abs(llvm::Value *in1); + llvm::Value *arl(llvm::Value *in1); + llvm::Value *add(llvm::Value *in1, llvm::Value *in2); + void beginLoop(); + void bgnSub(unsigned); + void brk(); + void cal(int label, llvm::Value *input); + llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); + llvm::Value *cos(llvm::Value *in); + llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); + llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); + void elseop(); + void endif(); + void endLoop(); + void end(); + void endSub(); + llvm::Value *ex2(llvm::Value *in); + llvm::Value *floor(llvm::Value *in); + llvm::Value *frc(llvm::Value *in); + void ifop(llvm::Value *in); + llvm::Value *kilp(llvm::Value *in); + llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in3); + llvm::Value *lit(llvm::Value *in); + llvm::Value *lg2(llvm::Value *in); + llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, + llvm::Value *in2); + llvm::Value *min(llvm::Value *in1, llvm::Value *in2); + llvm::Value *max(llvm::Value *in1, llvm::Value *in2); + llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); + llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); + llvm::Value *rcp(llvm::Value *in); + llvm::Value *rsq(llvm::Value *in); + llvm::Value *scs(llvm::Value *in); + llvm::Value *sge(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sin(llvm::Value *in); + llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); + llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); + llvm::Value *trunc(llvm::Value *in); + + void printVector(llvm::Value *val); +private: + const char *name(const char *prefix); + + llvm::Value *callFAbs(llvm::Value *val); + llvm::Value *callFloor(llvm::Value *val); + llvm::Value *callFSqrt(llvm::Value *val); + llvm::Value *callFLog(llvm::Value *val); + llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); + + llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w=0); + + llvm::Value *constVector(float x, float y, float z, float w); + + llvm::Function *declarePrintf(); + llvm::Function *declareFunc(int label); + + llvm::Function *findFunction(int label); + + std::vector extractVector(llvm::Value *vec); +private: + llvm::Module *m_mod; + llvm::Function *m_func; + char m_name[32]; + llvm::LLVMFoldingBuilder m_builder; + int m_idx; + + llvm::VectorType *m_floatVecType; + + llvm::Function *m_llvmFSqrt; + llvm::Function *m_llvmFAbs; + llvm::Function *m_llvmPow; + llvm::Function *m_llvmFloor; + llvm::Function *m_llvmFlog; + llvm::Function *m_llvmLit; + + llvm::Constant *m_fmtPtr; + + std::stack m_ifStack; + struct Loop { + llvm::BasicBlock *begin; + llvm::BasicBlock *end; + }; + std::stack m_loopStack; + std::map m_functions; + Storage *m_storage; +}; + +#endif diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp new file mode 100644 index 0000000000..a4d5046637 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -0,0 +1,121 @@ +#include "instructionssoa.h" + +#include "storagesoa.h" + +#include + +using namespace llvm; + +InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, + llvm::BasicBlock *block, StorageSoa *storage) + : m_builder(block), + m_storage(storage), + m_idx(0) +{ +} + +const char * InstructionsSoa::name(const char *prefix) const +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + Constant *constVector = Constant::getNullValue(vectorType); + Value *res = m_builder.CreateInsertElement(constVector, x, + m_storage->constantInt(0), + name("vecx")); + res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), + name("vecxy")); + res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), + name("vecxyz")); + if (w) + res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), + name("vecxyzw")); + return res; +} + +std::vector InstructionsSoa::arl(const std::vector in) +{ + std::vector res(4); + + //Extract x's + llvm::Value *x1 = m_builder.CreateExtractElement(in[0], + m_storage->constantInt(0), + name("extractX")); + //cast it to an unsigned int + x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); + + res[0] = x1;//vectorFromVals(x1, x2, x3, x4); + //only x is valid. the others shouldn't be necessary + /* + res[1] = Constant::getNullValue(m_floatVecType); + res[2] = Constant::getNullValue(m_floatVecType); + res[3] = Constant::getNullValue(m_floatVecType); + */ + + return res; +} + + +std::vector InstructionsSoa::add(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); + res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); + res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); + res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); + + return res; +} + +std::vector InstructionsSoa::mul(const std::vector in1, + const std::vector in2) +{ + std::vector res(4); + + res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); + res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); + res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); + res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); + + return res; +} + +void InstructionsSoa::end() +{ + m_builder.CreateRetVoid(); +} + +std::vector InstructionsSoa::madd(const std::vector in1, + const std::vector in2, + const std::vector in3) +{ + std::vector res = mul(in1, in2); + return add(res, in3); +} + +std::vector InstructionsSoa::extractVector(llvm::Value *vector) +{ + std::vector res(4); + res[0] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(0), + name("extract1X")); + res[1] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(1), + name("extract2X")); + res[2] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(2), + name("extract3X")); + res[3] = m_builder.CreateExtractElement(vector, + m_storage->constantInt(3), + name("extract4X")); + + return res; +} diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h new file mode 100644 index 0000000000..4169dcbb2e --- /dev/null +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -0,0 +1,74 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INSTRUCTIONSSOA_H +#define INSTRUCTIONSSOA_H + +#include + +#include + +namespace llvm { + class Module; + class Function; + class BasicBlock; + class Value; +} +class StorageSoa; + +class InstructionsSoa +{ +public: + InstructionsSoa(llvm::Module *mod, llvm::Function *func, + llvm::BasicBlock *block, StorageSoa *storage); + + std::vector arl(const std::vector in); + + std::vector add(const std::vector in1, + const std::vector in2); + std::vector madd(const std::vector in1, + const std::vector in2, + const std::vector in3); + std::vector mul(const std::vector in1, + const std::vector in2); + void end(); + + std::vector extractVector(llvm::Value *vector); +private: + const char * name(const char *prefix) const; + llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, + llvm::Value *z, llvm::Value *w); +private: + llvm::LLVMFoldingBuilder m_builder; + StorageSoa *m_storage; +private: + mutable int m_idx; + mutable char m_name[32]; +}; + + +#endif diff --git a/src/gallium/auxiliary/gallivm/llvm_builtins.c b/src/gallium/auxiliary/gallivm/llvm_builtins.c new file mode 100644 index 0000000000..4f98d754ba --- /dev/null +++ b/src/gallium/auxiliary/gallivm/llvm_builtins.c @@ -0,0 +1,115 @@ +/*clang --emit-llvm llvm_builtins.c |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=gallivm_builtins.cpp -f -for=shader -funcname=createGallivmBuiltins*/ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +typedef __attribute__(( ocu_vector_type(4) )) float float4; + +extern float powf(float a, float b); + +inline float approx(float a, float b) +{ + if (b < -128.0f) b = -128.0f; + if (b > 128.0f) b = 128.0f; + if (a < 0) a = 0; + return powf(a, b); +} + +inline float4 lit(float4 tmp) +{ + float4 result; + result.x = 1.0; + result.w = 1.0; + if (tmp.x > 0) { + result.y = tmp.x; + result.z = approx(tmp.y, tmp.w); + } else { + result.y = 0; + result.z = 0; + } + return result; +} + +inline float4 cmp(float4 tmp0, float4 tmp1, float4 tmp2) +{ + float4 result; + + result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; + result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; + result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; + result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; + + return result; +} + +extern float cosf(float val); +extern float sinf(float val); + +inline float4 vcos(float4 val) +{ + float4 result; + printf("VEC IN is %f %f %f %f\n", val.x, val.y, val.z, val.w); + result.x = cosf(val.x); + result.y = cosf(val.x); + result.z = cosf(val.x); + result.w = cosf(val.x); + printf("VEC OUT is %f %f %f %f\n", result.x, result.y, result.z, result.w); + return result; +} + +inline float4 scs(float4 val) +{ + float4 result; + float tmp = val.x; + result.x = cosf(tmp); + result.y = sinf(tmp); + return result; +} + + +inline float4 vsin(float4 val) +{ + float4 result; + float tmp = val.x; + float res = sinf(tmp); + result.x = res; + result.y = res; + result.z = res; + result.w = res; + return result; +} + +inline int kilp(float4 val) +{ + if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) + return 1; + else + return 0; +} diff --git a/src/gallium/auxiliary/gallivm/loweringpass.cpp b/src/gallium/auxiliary/gallivm/loweringpass.cpp new file mode 100644 index 0000000000..556dbec366 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/loweringpass.cpp @@ -0,0 +1,17 @@ +#include "loweringpass.h" + +using namespace llvm; + +char LoweringPass::ID = 0; +RegisterPass X("lowering", "Lowering Pass"); + +LoweringPass::LoweringPass() + : ModulePass((intptr_t)&ID) +{ +} + +bool LoweringPass::runOnModule(Module &m) +{ + llvm::cerr << "Hello: " << m.getModuleIdentifier() << "\n"; + return false; +} diff --git a/src/gallium/auxiliary/gallivm/loweringpass.h b/src/gallium/auxiliary/gallivm/loweringpass.h new file mode 100644 index 0000000000..f62dcf6ba7 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/loweringpass.h @@ -0,0 +1,15 @@ +#ifndef LOWERINGPASS_H +#define LOWERINGPASS_H + +#include "llvm/Pass.h" +#include "llvm/Module.h" + +struct LoweringPass : public llvm::ModulePass +{ + static char ID; + LoweringPass(); + + virtual bool runOnModule(llvm::Module &m); +}; + +#endif diff --git a/src/gallium/auxiliary/gallivm/storage.cpp b/src/gallium/auxiliary/gallivm/storage.cpp new file mode 100644 index 0000000000..c4326de8c5 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storage.cpp @@ -0,0 +1,364 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ +#ifdef MESA_LLVM + +#include "storage.h" + +#include "gallivm_p.h" + +#include "pipe/p_shader_tokens.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace llvm; + +Storage::Storage(llvm::BasicBlock *block, llvm::Value *input) + : m_block(block), + m_INPUT(input), + m_addrs(32), + m_idx(0) +{ + m_floatVecType = VectorType::get(Type::FloatTy, 4); + m_intVecType = VectorType::get(IntegerType::get(32), 4); + + m_undefFloatVec = UndefValue::get(m_floatVecType); + m_undefIntVec = UndefValue::get(m_intVecType); + m_extSwizzleVec = 0; + + m_numConsts = 0; +} + +//can only build vectors with all members in the [0, 9] range +llvm::Constant *Storage::shuffleMask(int vec) +{ + if (!m_extSwizzleVec) { + std::vector elems; + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); + elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); + m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); + } + + if (m_intVecs.find(vec) != m_intVecs.end()) { + return m_intVecs[vec]; + } + int origVec = vec; + Constant* const_vec = 0; + if (origVec == 0) { + const_vec = Constant::getNullValue(m_intVecType); + } else { + int x = gallivm_x_swizzle(vec); + int y = gallivm_y_swizzle(vec); + int z = gallivm_z_swizzle(vec); + int w = gallivm_w_swizzle(vec); + std::vector elems; + elems.push_back(constantInt(x)); + elems.push_back(constantInt(y)); + elems.push_back(constantInt(z)); + elems.push_back(constantInt(w)); + const_vec = ConstantVector::get(m_intVecType, elems); + } + + m_intVecs[origVec] = const_vec; + return const_vec; +} + +llvm::ConstantInt *Storage::constantInt(int idx) +{ + if (m_constInts.find(idx) != m_constInts.end()) { + return m_constInts[idx]; + } + ConstantInt *const_int = ConstantInt::get(APInt(32, idx)); + m_constInts[idx] = const_int; + return const_int; +} + +llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx) +{ + Value *val = element(InputsArg, idx, indIdx); + LoadInst *load = new LoadInst(val, name("input"), false, m_block); + load->setAlignment(8); + + return load; +} + +llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx) +{ + m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts; + + Value *elem = element(ConstsArg, idx, indIdx); + LoadInst *load = new LoadInst(elem, name("const"), false, m_block); + load->setAlignment(8); + return load; +} + +llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) +{ + Constant *mask = shuffleMask(shuffle); + ShuffleVectorInst *res = + new ShuffleVectorInst(vec, m_extSwizzleVec, mask, + name("shuffle"), m_block); + return res; +} + + +llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx) +{ + Value *elem = element(TempsArg, idx, indIdx); + + LoadInst *load = new LoadInst(elem, name("temp"), false, m_block); + load->setAlignment(8); + + return load; +} + +void Storage::setTempElement(int idx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = 0; + if (m_tempWriteMap[idx]) + templ = tempElement(idx); + val = maskWrite(val, mask, templ); + } + Value *elem = element(TempsArg, idx); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); + m_tempWriteMap[idx] = true; +} + +void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = 0; + if (m_destWriteMap[dstIdx]) + templ = outputElement(dstIdx); + val = maskWrite(val, mask, templ); + } + + Value *elem = element(DestsArg, dstIdx); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); + m_destWriteMap[dstIdx] = true; +} + +llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) +{ + llvm::Value *dst = templ; + if (!dst) + dst = Constant::getNullValue(m_floatVecType); + if ((mask & TGSI_WRITEMASK_X)) { + llvm::Value *x = new ExtractElementInst(src, unsigned(0), + name("x"), m_block); + dst = new InsertElementInst(dst, x, unsigned(0), + name("dstx"), m_block); + } + if ((mask & TGSI_WRITEMASK_Y)) { + llvm::Value *y = new ExtractElementInst(src, unsigned(1), + name("y"), m_block); + dst = new InsertElementInst(dst, y, unsigned(1), + name("dsty"), m_block); + } + if ((mask & TGSI_WRITEMASK_Z)) { + llvm::Value *z = new ExtractElementInst(src, unsigned(2), + name("z"), m_block); + dst = new InsertElementInst(dst, z, unsigned(2), + name("dstz"), m_block); + } + if ((mask & TGSI_WRITEMASK_W)) { + llvm::Value *w = new ExtractElementInst(src, unsigned(3), + name("w"), m_block); + dst = new InsertElementInst(dst, w, unsigned(3), + name("dstw"), m_block); + } + return dst; +} + +const char * Storage::name(const char *prefix) +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +int Storage::numConsts() const +{ + return m_numConsts; +} + +llvm::Value * Storage::addrElement(int idx) const +{ + Value *ret = m_addrs[idx]; + if (!ret) + return m_undefFloatVec; + return ret; +} + +void Storage::setAddrElement(int idx, llvm::Value *val, int mask) +{ + if (mask != TGSI_WRITEMASK_XYZW) { + llvm::Value *templ = m_addrs[idx]; + val = maskWrite(val, mask, templ); + } + m_addrs[idx] = val; +} + +llvm::Value * Storage::extractIndex(llvm::Value *vec) +{ + llvm::Value *x = new ExtractElementInst(vec, unsigned(0), + name("x"), m_block); + return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block); +} + +void Storage::setCurrentBlock(llvm::BasicBlock *block) +{ + m_block = block; +} + +llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx) +{ + Value *elem = element(DestsArg, idx, indIdx); + LoadInst *load = new LoadInst(elem, name("output"), false, m_block); + load->setAlignment(8); + + return load; +} + +llvm::Value * Storage::inputPtr() const +{ + return m_INPUT; +} + +void Storage::pushArguments(llvm::Value *input) +{ + m_argStack.push(m_INPUT); + + m_INPUT = input; +} + +void Storage::popArguments() +{ + m_INPUT = m_argStack.top(); + m_argStack.pop(); +} + +void Storage::pushTemps() +{ + m_extSwizzleVec = 0; +} + +void Storage::popTemps() +{ +} + +llvm::Value * Storage::immediateElement(int idx) +{ + return m_immediates[idx]; +} + +void Storage::addImmediate(float *val) +{ + std::vector vec(4); + vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0])); + vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1])); + vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2])); + vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3])); + m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); +} + + +llvm::Value * Storage::elemPtr(Args arg) +{ + std::vector indices; + indices.push_back(constantInt(0)); + indices.push_back(constantInt(static_cast(arg))); + GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, + indices.begin(), + indices.end(), + name("input_ptr"), + m_block); + return new LoadInst(getElem, name("input_field"), false, m_block); +} + +llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, + llvm::Value *indIdx ) +{ + GetElementPtrInst *getElem = 0; + + if (indIdx) { + getElem = new GetElementPtrInst(ptr, + BinaryOperator::create(Instruction::Add, + indIdx, + constantInt(idx), + name("add"), + m_block), + name("field"), + m_block); + } else { + getElem = new GetElementPtrInst(ptr, + constantInt(idx), + name("field"), + m_block); + } + return getElem; +} + +llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx ) +{ + Value *val = elemPtr(arg); + return elemIdx(val, idx, indIdx); +} + +void Storage::setKilElement(llvm::Value *val) +{ + std::vector indices; + indices.push_back(constantInt(0)); + indices.push_back(constantInt(static_cast(KilArg))); + GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, + indices.begin(), + indices.end(), + name("kil_ptr"), + m_block); + StoreInst *st = new StoreInst(val, elem, false, m_block); + st->setAlignment(8); +} + +#endif //MESA_LLVM + + diff --git a/src/gallium/auxiliary/gallivm/storage.h b/src/gallium/auxiliary/gallivm/storage.h new file mode 100644 index 0000000000..8574f7554e --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storage.h @@ -0,0 +1,133 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Zack Rusin zack@tungstengraphics.com + */ + +#ifndef STORAGE_H +#define STORAGE_H + +#include +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class LoadInst; + class Value; + class VectorType; +} + +class Storage +{ +public: + Storage(llvm::BasicBlock *block, + llvm::Value *input); + + llvm::Value *inputPtr() const; + + void setCurrentBlock(llvm::BasicBlock *block); + + llvm::ConstantInt *constantInt(int); + llvm::Constant *shuffleMask(int vec); + llvm::Value *inputElement(int idx, llvm::Value *indIdx =0); + llvm::Value *constElement(int idx, llvm::Value *indIdx =0); + llvm::Value *outputElement(int idx, llvm::Value *indIdx =0); + llvm::Value *tempElement(int idx, llvm::Value *indIdx =0); + llvm::Value *immediateElement(int idx); + + void setOutputElement(int dstIdx, llvm::Value *val, int mask); + void setTempElement(int idx, llvm::Value *val, int mask); + + llvm::Value *addrElement(int idx) const; + void setAddrElement(int idx, llvm::Value *val, int mask); + + void setKilElement(llvm::Value *val); + + llvm::Value *shuffleVector(llvm::Value *vec, int shuffle); + + llvm::Value *extractIndex(llvm::Value *vec); + + int numConsts() const; + + void pushArguments(llvm::Value *input); + void popArguments(); + void pushTemps(); + void popTemps(); + + void addImmediate(float *val); + +private: + llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ); + const char *name(const char *prefix); + + enum Args { + DestsArg = 0, + InputsArg = 1, + TempsArg = 2, + ConstsArg = 3, + KilArg = 4 + }; + llvm::Value *elemPtr(Args arg); + llvm::Value *elemIdx(llvm::Value *ptr, int idx, + llvm::Value *indIdx = 0); + llvm::Value *element(Args arg, int idx, llvm::Value *indIdx = 0); + +private: + llvm::BasicBlock *m_block; + llvm::Value *m_INPUT; + + std::map m_constInts; + std::map m_intVecs; + std::vector m_addrs; + std::vector m_immediates; + + llvm::VectorType *m_floatVecType; + llvm::VectorType *m_intVecType; + + char m_name[32]; + int m_idx; + + int m_numConsts; + + std::map m_destWriteMap; + std::map m_tempWriteMap; + + llvm::Value *m_undefFloatVec; + llvm::Value *m_undefIntVec; + llvm::Value *m_extSwizzleVec; + + std::stack m_argStack; + std::stack > m_tempStack; +}; + +#endif diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp new file mode 100644 index 0000000000..ed0674a96f --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -0,0 +1,389 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "storagesoa.h" + +#include "gallivm_p.h" + +#include "pipe/p_shader_tokens.h" +#include "pipe/p_debug.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace llvm; + + +StorageSoa::StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps) + : m_block(block), + m_input(input), + m_output(output), + m_consts(consts), + m_temps(temps), + m_immediates(0), + m_idx(0) +{ +} + +void StorageSoa::addImmediate(float *vec) +{ + std::vector vals(4); + vals[0] = vec[0]; + vals[1] = vec[1]; + vals[2] = vec[2]; + vals[3] = vec[3]; + m_immediatesToFlush.push_back(vals); +} + +void StorageSoa::declareImmediates() +{ + if (m_immediatesToFlush.empty()) + return; + + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorChannels = ArrayType::get(vectorType, 4); + ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); + + m_immediates = new GlobalVariable( + /*Type=*/arrayType, + /*isConstant=*/false, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name("immediates"), + currentModule()); + + std::vector arrayVals; + for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { + std::vector vec = m_immediatesToFlush[i]; + std::vector vals(4); + std::vector channelArray; + + vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; + llvm::Constant *xChannel = createConstGlobalVector(vals); + + vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; + llvm::Constant *yChannel = createConstGlobalVector(vals); + + vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; + llvm::Constant *zChannel = createConstGlobalVector(vals); + + vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; + llvm::Constant *wChannel = createConstGlobalVector(vals); + channelArray.push_back(xChannel); + channelArray.push_back(yChannel); + channelArray.push_back(zChannel); + channelArray.push_back(wChannel); + Constant *constChannels = ConstantArray::get(vectorChannels, + channelArray); + arrayVals.push_back(constChannels); + } + Constant *constArray = ConstantArray::get(arrayType, arrayVals); + m_immediates->setInitializer(constArray); + + m_immediatesToFlush.clear(); +} + +llvm::Value *StorageSoa::addrElement(int idx) const +{ + std::map::const_iterator itr = m_addresses.find(idx); + if (itr == m_addresses.end()) { + debug_printf("Trying to access invalid shader 'address'\n"); + return 0; + } + llvm::Value * res = (*itr).second; + + res = new LoadInst(res, name("addr"), false, m_block); + + return res; +} + +std::vector StorageSoa::inputElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_input, idx, 0); + res[1] = element(m_input, idx, 1); + res[2] = element(m_input, idx, 2); + res[3] = element(m_input, idx, 3); + + return res; +} + +std::vector StorageSoa::constElement(llvm::Value *idx) +{ + std::vector res(4); + llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; + + xChannel = elementPointer(m_consts, idx, 0); + yChannel = elementPointer(m_consts, idx, 1); + zChannel = elementPointer(m_consts, idx, 2); + wChannel = elementPointer(m_consts, idx, 3); + + res[0] = alignedArrayLoad(xChannel); + res[1] = alignedArrayLoad(yChannel); + res[2] = alignedArrayLoad(zChannel); + res[3] = alignedArrayLoad(wChannel); + + return res; +} + +std::vector StorageSoa::outputElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_output, idx, 0); + res[1] = element(m_output, idx, 1); + res[2] = element(m_output, idx, 2); + res[3] = element(m_output, idx, 3); + + return res; +} + +std::vector StorageSoa::tempElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_temps, idx, 0); + res[1] = element(m_temps, idx, 1); + res[2] = element(m_temps, idx, 2); + res[3] = element(m_temps, idx, 3); + + return res; +} + +std::vector StorageSoa::immediateElement(llvm::Value *idx) +{ + std::vector res(4); + + res[0] = element(m_immediates, idx, 0); + res[1] = element(m_immediates, idx, 1); + res[2] = element(m_immediates, idx, 2); + res[3] = element(m_immediates, idx, 3); + + return res; +} + +llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, + int channel) const +{ + std::vector indices; + if (m_immediates == ptr) + indices.push_back(constantInt(0)); + indices.push_back(index); + indices.push_back(constantInt(channel)); + + GetElementPtrInst *getElem = new GetElementPtrInst(ptr, + indices.begin(), + indices.end(), + name("ptr"), + m_block); + return getElem; +} + +llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, + int channel) const +{ + llvm::Value *res = elementPointer(ptr, index, channel); + LoadInst *load = new LoadInst(res, name("element"), false, m_block); + //load->setAlignment(8); + return load; +} + +const char * StorageSoa::name(const char *prefix) const +{ + ++m_idx; + snprintf(m_name, 32, "%s%d", prefix, m_idx); + return m_name; +} + +llvm::ConstantInt * StorageSoa::constantInt(int idx) const +{ + if (m_constInts.find(idx) != m_constInts.end()) { + return m_constInts[idx]; + } + ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); + m_constInts[idx] = constInt; + return constInt; +} + +llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + PointerType *vectorPtr = PointerType::get(vectorType, 0); + + CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); + LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); + load->setAlignment(8); + return load; +} + +llvm::Module * StorageSoa::currentModule() const +{ + if (!m_block || !m_block->getParent()) + return 0; + + return m_block->getParent()->getParent(); +} + +llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &vec) +{ + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + std::vector immValues; + ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); + ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); + ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); + ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); + immValues.push_back(constx); + immValues.push_back(consty); + immValues.push_back(constz); + immValues.push_back(constw); + Constant *constVector = ConstantVector::get(vectorType, immValues); + + return constVector; +} + +std::vector StorageSoa::load(Argument type, int idx, int swizzle, + llvm::Value *indIdx) +{ + std::vector val(4); + + //if we have an indirect index, always use that + // if not use the integer offset to create one + llvm::Value *realIndex = 0; + if (indIdx) + realIndex = indIdx; + else + realIndex = constantInt(idx); + debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); + + switch(type) { + case Input: + val = inputElement(realIndex); + break; + case Output: + val = outputElement(realIndex); + break; + case Temp: + val = tempElement(realIndex); + break; + case Const: + val = constElement(realIndex); + break; + case Immediate: + val = immediateElement(realIndex); + break; + case Address: + debug_printf("Address not handled in the load phase!\n"); + assert(0); + break; + } + if (!gallivm_is_swizzle(swizzle)) + return val; + + std::vector res(4); + + res[0] = val[gallivm_x_swizzle(swizzle)]; + res[1] = val[gallivm_y_swizzle(swizzle)]; + res[2] = val[gallivm_z_swizzle(swizzle)]; + res[3] = val[gallivm_w_swizzle(swizzle)]; + return res; +} + +void StorageSoa::store(Argument type, int idx, const std::vector &val, + int mask) +{ + llvm::Value *out = 0; + switch(type) { + case Output: + out = m_output; + break; + case Temp: + out = m_temps; + break; + case Input: + out = m_input; + break; + case Address: { + llvm::Value *addr = m_addresses[idx]; + if (!addr) { + addAddress(idx); + addr = m_addresses[idx]; + assert(addr); + } + new StoreInst(val[0], addr, false, m_block); + return; + break; + } + default: + debug_printf("Can't save output of this type: %d !\n", type); + assert(0); + break; + } + llvm::Value *realIndex = constantInt(idx); + if ((mask & TGSI_WRITEMASK_X)) { + llvm::Value *xChannel = elementPointer(out, realIndex, 0); + new StoreInst(val[0], xChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_Y)) { + llvm::Value *yChannel = elementPointer(out, realIndex, 1); + new StoreInst(val[1], yChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_Z)) { + llvm::Value *zChannel = elementPointer(out, realIndex, 2); + new StoreInst(val[2], zChannel, false, m_block); + } + if ((mask & TGSI_WRITEMASK_W)) { + llvm::Value *wChannel = elementPointer(out, realIndex, 3); + new StoreInst(val[3], wChannel, false, m_block); + } +} + +void StorageSoa::addAddress(int idx) +{ + GlobalVariable *val = new GlobalVariable( + /*Type=*/IntegerType::get(32), + /*isConstant=*/false, + /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, // has initializer, specified below + /*Name=*/name("address"), + currentModule()); + val->setInitializer(Constant::getNullValue(IntegerType::get(32))); + + debug_printf("adding to %d\n", idx); + m_addresses[idx] = val; +} diff --git a/src/gallium/auxiliary/gallivm/storagesoa.h b/src/gallium/auxiliary/gallivm/storagesoa.h new file mode 100644 index 0000000000..6443351f27 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/storagesoa.h @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef STORAGESOA_H +#define STORAGESOA_H + +#include +#include +#include + +namespace llvm { + class BasicBlock; + class Constant; + class ConstantInt; + class GlobalVariable; + class LoadInst; + class Value; + class VectorType; + class Module; +} + +class StorageSoa +{ +public: + enum Argument { + Input, + Output, + Temp, + Const, + Immediate, + Address + }; +public: + StorageSoa(llvm::BasicBlock *block, + llvm::Value *input, + llvm::Value *output, + llvm::Value *consts, + llvm::Value *temps); + + + std::vector load(Argument type, int idx, int swizzle, + llvm::Value *indIdx =0); + void store(Argument type, int idx, const std::vector &val, + int mask); + + void addImmediate(float *vec); + void declareImmediates(); + + void addAddress(int idx); + + llvm::Value * addrElement(int idx) const; + + llvm::ConstantInt *constantInt(int) const; +private: + llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, + int channel) const; + llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, + int channel) const; + const char *name(const char *prefix) const; + llvm::Value *alignedArrayLoad(llvm::Value *val); + llvm::Module *currentModule() const; + llvm::Constant *createConstGlobalVector(const std::vector &vec); + + std::vector inputElement(llvm::Value *indIdx); + std::vector constElement(llvm::Value *indIdx); + std::vector outputElement(llvm::Value *indIdx); + std::vector tempElement(llvm::Value *indIdx); + std::vector immediateElement(llvm::Value *indIdx); +private: + llvm::BasicBlock *m_block; + + llvm::Value *m_input; + llvm::Value *m_output; + llvm::Value *m_consts; + llvm::Value *m_temps; + llvm::GlobalVariable *m_immediates; + + std::map m_addresses; + + std::vector > m_immediatesToFlush; + + mutable std::map m_constInts; + mutable char m_name[32]; + mutable int m_idx; +}; + +#endif diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp new file mode 100644 index 0000000000..2cb4acce32 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -0,0 +1,1221 @@ +#include "tgsitollvm.h" + +#include "gallivm.h" +#include "gallivm_p.h" + +#include "storage.h" +#include "instructions.h" +#include "storagesoa.h" +#include "instructionssoa.h" + +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/exec/tgsi_exec.h" +#include "tgsi/util/tgsi_util.h" +#include "tgsi/util/tgsi_build.h" +#include "tgsi/util/tgsi_dump.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +using namespace llvm; + +static inline FunctionType *vertexShaderFunctionType() +{ + //Function takes three arguments, + // the calling code has to make sure the types it will + // pass are castable to the following: + // [4 x <4 x float>] inputs, + // [4 x <4 x float>] output, + // [4 x [4 x float]] consts, + // [4 x <4 x float>] temps + + std::vector funcArgs; + VectorType *vectorType = VectorType::get(Type::FloatTy, 4); + ArrayType *vectorArray = ArrayType::get(vectorType, 4); + PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); + + ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); + ArrayType *constsArray = ArrayType::get(floatArray, 4); + PointerType *constsArrayPtr = PointerType::get(constsArray, 0); + + funcArgs.push_back(vectorArrayPtr);//inputs + funcArgs.push_back(vectorArrayPtr);//output + funcArgs.push_back(constsArrayPtr);//consts + funcArgs.push_back(vectorArrayPtr);//temps + + FunctionType *functionType = FunctionType::get( + /*Result=*/Type::VoidTy, + /*Params=*/funcArgs, + /*isVarArg=*/false); + + return functionType; +} + +static inline void +add_interpolator(struct gallivm_ir *ir, + struct gallivm_interpolate *interp) +{ + ir->interpolators[ir->num_interp] = *interp; + ++ir->num_interp; +} + +static void +translate_declaration(struct gallivm_ir *prog, + llvm::Module *module, + Storage *storage, + struct tgsi_full_declaration *decl, + struct tgsi_full_declaration *fd) +{ + if (decl->Declaration.File == TGSI_FILE_INPUT) { + unsigned first, last, mask; + uint interp_method; + + assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + /* Do not touch WPOS.xy */ + if (first == 0) { + mask &= ~TGSI_WRITEMASK_XY; + if (mask == TGSI_WRITEMASK_NONE) { + first++; + if (first > last) { + return; + } + } + } + + interp_method = decl->Interpolation.Interpolate; + + if (mask == TGSI_WRITEMASK_XYZW) { + unsigned i, j; + + for (i = first; i <= last; i++) { + for (j = 0; j < NUM_CHANNELS; j++) { + //interp( mach, i, j ); + struct gallivm_interpolate interp; + interp.type = interp_method; + interp.attrib = i; + interp.chan = j; + add_interpolator(prog, &interp); + } + } + } else { + unsigned i, j; + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + struct gallivm_interpolate interp; + interp.type = interp_method; + interp.attrib = i; + interp.chan = j; + add_interpolator(prog, &interp); + } + } + } + } + } +} + +static void +translate_declarationir(struct gallivm_ir *, + llvm::Module *, + StorageSoa *storage, + struct tgsi_full_declaration *decl, + struct tgsi_full_declaration *) +{ + if (decl->Declaration.File == TGSI_FILE_ADDRESS) { + int idx = decl->u.DeclarationRange.First; + storage->addAddress(idx); + } +} + +static void +translate_immediate(Storage *storage, + struct tgsi_full_immediate *imm) +{ + float vec[4]; + int i; + for (i = 0; i < imm->Immediate.Size - 1; ++i) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + vec[i] = imm->u.ImmediateFloat32[i].Float; + break; + default: + assert(0); + } + } + storage->addImmediate(vec); +} + + +static void +translate_immediateir(StorageSoa *storage, + struct tgsi_full_immediate *imm) +{ + float vec[4]; + int i; + for (i = 0; i < imm->Immediate.Size - 1; ++i) { + switch (imm->Immediate.DataType) { + case TGSI_IMM_FLOAT32: + vec[i] = imm->u.ImmediateFloat32[i].Float; + break; + default: + assert(0); + } + } + storage->addImmediate(vec); +} + +static inline int +swizzleInt(struct tgsi_full_src_register *src) +{ + int swizzle = 0; + int start = 1000; + + for (int k = 0; k < 4; ++k) { + swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start; + start /= 10; + } + return swizzle; +} + +static inline llvm::Value * +swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src, + Storage *storage) +{ + int swizzle = swizzleInt(src); + + if (gallivm_is_swizzle(swizzle)) { + /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/ + val = storage->shuffleVector(val, swizzle); + } + return val; +} + +static void +translate_instruction(llvm::Module *module, + Storage *storage, + Instructions *instr, + struct tgsi_full_instruction *inst, + struct tgsi_full_instruction *fi, + unsigned instno) +{ + llvm::Value *inputs[4]; + inputs[0] = 0; + inputs[1] = 0; + inputs[2] = 0; + inputs[3] = 0; + + for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + llvm::Value *val = 0; + llvm::Value *indIdx = 0; + + if (src->SrcRegister.Indirect) { + indIdx = storage->addrElement(src->SrcRegisterInd.Index); + indIdx = storage->extractIndex(indIdx); + } + if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { + val = storage->constElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { + val = storage->inputElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { + val = storage->tempElement(src->SrcRegister.Index); + } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { + val = storage->outputElement(src->SrcRegister.Index, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { + val = storage->immediateElement(src->SrcRegister.Index); + } else { + fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); + return; + } + + inputs[i] = swizzleVector(val, src, storage); + } + + /*if (inputs[0]) + instr->printVector(inputs[0]); + if (inputs[1]) + instr->printVector(inputs[1]);*/ + llvm::Value *out = 0; + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: { + out = instr->arl(inputs[0]); + } + break; + case TGSI_OPCODE_MOV: { + out = inputs[0]; + } + break; + case TGSI_OPCODE_LIT: { + out = instr->lit(inputs[0]); + } + break; + case TGSI_OPCODE_RCP: { + out = instr->rcp(inputs[0]); + } + break; + case TGSI_OPCODE_RSQ: { + out = instr->rsq(inputs[0]); + } + break; + case TGSI_OPCODE_EXP: + break; + case TGSI_OPCODE_LOG: + break; + case TGSI_OPCODE_MUL: { + out = instr->mul(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_ADD: { + out = instr->add(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP3: { + out = instr->dp3(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP4: { + out = instr->dp4(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DST: { + out = instr->dst(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MIN: { + out = instr->min(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MAX: { + out = instr->max(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SLT: { + out = instr->slt(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SGE: { + out = instr->sge(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MAD: { + out = instr->madd(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SUB: { + out = instr->sub(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_LERP: { + out = instr->lerp(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_CND: + break; + case TGSI_OPCODE_CND0: + break; + case TGSI_OPCODE_DOT2ADD: + break; + case TGSI_OPCODE_INDEX: + break; + case TGSI_OPCODE_NEGATE: + break; + case TGSI_OPCODE_FRAC: { + out = instr->frc(inputs[0]); + } + break; + case TGSI_OPCODE_CLAMP: + break; + case TGSI_OPCODE_FLOOR: { + out = instr->floor(inputs[0]); + } + break; + case TGSI_OPCODE_ROUND: + break; + case TGSI_OPCODE_EXPBASE2: { + out = instr->ex2(inputs[0]); + } + break; + case TGSI_OPCODE_LOGBASE2: { + out = instr->lg2(inputs[0]); + } + break; + case TGSI_OPCODE_POWER: { + out = instr->pow(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_CROSSPRODUCT: { + out = instr->cross(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_MULTIPLYMATRIX: + break; + case TGSI_OPCODE_ABS: { + out = instr->abs(inputs[0]); + } + break; + case TGSI_OPCODE_RCC: + break; + case TGSI_OPCODE_DPH: { + out = instr->dph(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_COS: { + out = instr->cos(inputs[0]); + } + break; + case TGSI_OPCODE_DDX: + break; + case TGSI_OPCODE_DDY: + break; + case TGSI_OPCODE_KILP: { + out = instr->kilp(inputs[0]); + storage->setKilElement(out); + return; + } + break; + case TGSI_OPCODE_PK2H: + break; + case TGSI_OPCODE_PK2US: + break; + case TGSI_OPCODE_PK4B: + break; + case TGSI_OPCODE_PK4UB: + break; + case TGSI_OPCODE_RFL: + break; + case TGSI_OPCODE_SEQ: + break; + case TGSI_OPCODE_SFL: + break; + case TGSI_OPCODE_SGT: { + out = instr->sgt(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_SIN: { + out = instr->sin(inputs[0]); + } + break; + case TGSI_OPCODE_SLE: + break; + case TGSI_OPCODE_SNE: + break; + case TGSI_OPCODE_STR: + break; + case TGSI_OPCODE_TEX: + break; + case TGSI_OPCODE_TXD: + break; + case TGSI_OPCODE_UP2H: + break; + case TGSI_OPCODE_UP2US: + break; + case TGSI_OPCODE_UP4B: + break; + case TGSI_OPCODE_UP4UB: + break; + case TGSI_OPCODE_X2D: + break; + case TGSI_OPCODE_ARA: + break; + case TGSI_OPCODE_ARR: + break; + case TGSI_OPCODE_BRA: + break; + case TGSI_OPCODE_CAL: { + instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr()); + return; + } + break; + case TGSI_OPCODE_RET: { + instr->end(); + return; + } + break; + case TGSI_OPCODE_SSG: + break; + case TGSI_OPCODE_CMP: { + out = instr->cmp(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SCS: { + out = instr->scs(inputs[0]); + } + break; + case TGSI_OPCODE_TXB: + break; + case TGSI_OPCODE_NRM: + break; + case TGSI_OPCODE_DIV: + break; + case TGSI_OPCODE_DP2: + break; + case TGSI_OPCODE_TXL: + break; + case TGSI_OPCODE_BRK: { + instr->brk(); + return; + } + break; + case TGSI_OPCODE_IF: { + instr->ifop(inputs[0]); + storage->setCurrentBlock(instr->currentBlock()); + return; //just update the state + } + break; + case TGSI_OPCODE_LOOP: + break; + case TGSI_OPCODE_REP: + break; + case TGSI_OPCODE_ELSE: { + instr->elseop(); + storage->setCurrentBlock(instr->currentBlock()); + return; //only state update + } + break; + case TGSI_OPCODE_ENDIF: { + instr->endif(); + storage->setCurrentBlock(instr->currentBlock()); + return; //just update the state + } + break; + case TGSI_OPCODE_ENDLOOP: + break; + case TGSI_OPCODE_ENDREP: + break; + case TGSI_OPCODE_PUSHA: + break; + case TGSI_OPCODE_POPA: + break; + case TGSI_OPCODE_CEIL: + break; + case TGSI_OPCODE_I2F: + break; + case TGSI_OPCODE_NOT: + break; + case TGSI_OPCODE_TRUNC: { + out = instr->trunc(inputs[0]); + } + break; + case TGSI_OPCODE_SHL: + break; + case TGSI_OPCODE_SHR: + break; + case TGSI_OPCODE_AND: + break; + case TGSI_OPCODE_OR: + break; + case TGSI_OPCODE_MOD: + break; + case TGSI_OPCODE_XOR: + break; + case TGSI_OPCODE_SAD: + break; + case TGSI_OPCODE_TXF: + break; + case TGSI_OPCODE_TXQ: + break; + case TGSI_OPCODE_CONT: + break; + case TGSI_OPCODE_EMIT: + break; + case TGSI_OPCODE_ENDPRIM: + break; + case TGSI_OPCODE_BGNLOOP2: { + instr->beginLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } + break; + case TGSI_OPCODE_BGNSUB: { + instr->bgnSub(instno); + storage->setCurrentBlock(instr->currentBlock()); + storage->pushTemps(); + return; + } + break; + case TGSI_OPCODE_ENDLOOP2: { + instr->endLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } + break; + case TGSI_OPCODE_ENDSUB: { + instr->endSub(); + storage->setCurrentBlock(instr->currentBlock()); + storage->popArguments(); + storage->popTemps(); + return; + } + break; + case TGSI_OPCODE_NOISE1: + break; + case TGSI_OPCODE_NOISE2: + break; + case TGSI_OPCODE_NOISE3: + break; + case TGSI_OPCODE_NOISE4: + break; + case TGSI_OPCODE_NOP: + break; + case TGSI_OPCODE_TEXBEM: + break; + case TGSI_OPCODE_TEXBEML: + break; + case TGSI_OPCODE_TEXREG2AR: + break; + case TGSI_OPCODE_TEXM3X2PAD: + break; + case TGSI_OPCODE_TEXM3X2TEX: + break; + case TGSI_OPCODE_TEXM3X3PAD: + break; + case TGSI_OPCODE_TEXM3X3TEX: + break; + case TGSI_OPCODE_TEXM3X3SPEC: + break; + case TGSI_OPCODE_TEXM3X3VSPEC: + break; + case TGSI_OPCODE_TEXREG2GB: + break; + case TGSI_OPCODE_TEXREG2RGB: + break; + case TGSI_OPCODE_TEXDP3TEX: + break; + case TGSI_OPCODE_TEXDP3: + break; + case TGSI_OPCODE_TEXM3X3: + break; + case TGSI_OPCODE_TEXM3X2DEPTH: + break; + case TGSI_OPCODE_TEXDEPTH: + break; + case TGSI_OPCODE_BEM: + break; + case TGSI_OPCODE_M4X3: + break; + case TGSI_OPCODE_M3X4: + break; + case TGSI_OPCODE_M3X3: + break; + case TGSI_OPCODE_M3X2: + break; + case TGSI_OPCODE_NRM4: + break; + case TGSI_OPCODE_CALLNZ: + break; + case TGSI_OPCODE_IFC: + break; + case TGSI_OPCODE_BREAKC: + break; + case TGSI_OPCODE_KIL: + break; + case TGSI_OPCODE_END: + instr->end(); + return; + break; + default: + fprintf(stderr, "ERROR: Unknown opcode %d\n", + inst->Instruction.Opcode); + assert(0); + break; + } + + if (!out) { + fprintf(stderr, "ERROR: unsupported opcode %d\n", + inst->Instruction.Opcode); + assert(!"Unsupported opcode"); + } + + /* # not sure if we need this */ + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + case TGSI_SAT_ZERO_ONE: + /*TXT( "_SAT" );*/ + break; + case TGSI_SAT_MINUS_PLUS_ONE: + /*TXT( "_SAT[-1,1]" );*/ + break; + default: + assert( 0 ); + } + + /* store results */ + for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { + storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { + storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { + storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else { + fprintf(stderr, "ERROR: unsupported LLVM destination!"); + assert(!"wrong destination"); + } + } +} + + +static void +translate_instructionir(llvm::Module *module, + StorageSoa *storage, + InstructionsSoa *instr, + struct tgsi_full_instruction *inst, + struct tgsi_full_instruction *fi, + unsigned instno) +{ + std::vector< std::vector > inputs(inst->Instruction.NumSrcRegs); + + for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { + struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; + std::vector val; + llvm::Value *indIdx = 0; + int swizzle = swizzleInt(src); + + if (src->SrcRegister.Indirect) { + indIdx = storage->addrElement(src->SrcRegisterInd.Index); + } + if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { + val = storage->load(StorageSoa::Const, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { + val = storage->load(StorageSoa::Input, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { + val = storage->load(StorageSoa::Temp, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { + val = storage->load(StorageSoa::Output, + src->SrcRegister.Index, swizzle, indIdx); + } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { + val = storage->load(StorageSoa::Immediate, + src->SrcRegister.Index, swizzle, indIdx); + } else { + fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); + return; + } + + inputs[i] = val; + } + + std::vector out(4); + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: { + out = instr->arl(inputs[0]); + } + break; + case TGSI_OPCODE_MOV: { + out = inputs[0]; + } + break; + case TGSI_OPCODE_LIT: { + } + break; + case TGSI_OPCODE_RCP: { + } + break; + case TGSI_OPCODE_RSQ: { + } + break; + case TGSI_OPCODE_EXP: + break; + case TGSI_OPCODE_LOG: + break; + case TGSI_OPCODE_MUL: { + out = instr->mul(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_ADD: { + out = instr->add(inputs[0], inputs[1]); + } + break; + case TGSI_OPCODE_DP3: { + } + break; + case TGSI_OPCODE_DP4: { + } + break; + case TGSI_OPCODE_DST: { + } + break; + case TGSI_OPCODE_MIN: { + } + break; + case TGSI_OPCODE_MAX: { + } + break; + case TGSI_OPCODE_SLT: { + } + break; + case TGSI_OPCODE_SGE: { + } + break; + case TGSI_OPCODE_MAD: { + out = instr->madd(inputs[0], inputs[1], inputs[2]); + } + break; + case TGSI_OPCODE_SUB: { + } + break; + case TGSI_OPCODE_LERP: { + } + break; + case TGSI_OPCODE_CND: + break; + case TGSI_OPCODE_CND0: + break; + case TGSI_OPCODE_DOT2ADD: + break; + case TGSI_OPCODE_INDEX: + break; + case TGSI_OPCODE_NEGATE: + break; + case TGSI_OPCODE_FRAC: { + } + break; + case TGSI_OPCODE_CLAMP: + break; + case TGSI_OPCODE_FLOOR: { + } + break; + case TGSI_OPCODE_ROUND: + break; + case TGSI_OPCODE_EXPBASE2: { + } + break; + case TGSI_OPCODE_LOGBASE2: { + } + break; + case TGSI_OPCODE_POWER: { + } + break; + case TGSI_OPCODE_CROSSPRODUCT: { + } + break; + case TGSI_OPCODE_MULTIPLYMATRIX: + break; + case TGSI_OPCODE_ABS: { + } + break; + case TGSI_OPCODE_RCC: + break; + case TGSI_OPCODE_DPH: { + } + break; + case TGSI_OPCODE_COS: { + } + break; + case TGSI_OPCODE_DDX: + break; + case TGSI_OPCODE_DDY: + break; + case TGSI_OPCODE_KILP: { + } + break; + case TGSI_OPCODE_PK2H: + break; + case TGSI_OPCODE_PK2US: + break; + case TGSI_OPCODE_PK4B: + break; + case TGSI_OPCODE_PK4UB: + break; + case TGSI_OPCODE_RFL: + break; + case TGSI_OPCODE_SEQ: + break; + case TGSI_OPCODE_SFL: + break; + case TGSI_OPCODE_SGT: { + } + break; + case TGSI_OPCODE_SIN: { + } + break; + case TGSI_OPCODE_SLE: + break; + case TGSI_OPCODE_SNE: + break; + case TGSI_OPCODE_STR: + break; + case TGSI_OPCODE_TEX: + break; + case TGSI_OPCODE_TXD: + break; + case TGSI_OPCODE_UP2H: + break; + case TGSI_OPCODE_UP2US: + break; + case TGSI_OPCODE_UP4B: + break; + case TGSI_OPCODE_UP4UB: + break; + case TGSI_OPCODE_X2D: + break; + case TGSI_OPCODE_ARA: + break; + case TGSI_OPCODE_ARR: + break; + case TGSI_OPCODE_BRA: + break; + case TGSI_OPCODE_CAL: { + } + break; + case TGSI_OPCODE_RET: { + } + break; + case TGSI_OPCODE_SSG: + break; + case TGSI_OPCODE_CMP: { + } + break; + case TGSI_OPCODE_SCS: { + } + break; + case TGSI_OPCODE_TXB: + break; + case TGSI_OPCODE_NRM: + break; + case TGSI_OPCODE_DIV: + break; + case TGSI_OPCODE_DP2: + break; + case TGSI_OPCODE_TXL: + break; + case TGSI_OPCODE_BRK: { + } + break; + case TGSI_OPCODE_IF: { + } + break; + case TGSI_OPCODE_LOOP: + break; + case TGSI_OPCODE_REP: + break; + case TGSI_OPCODE_ELSE: { + } + break; + case TGSI_OPCODE_ENDIF: { + } + break; + case TGSI_OPCODE_ENDLOOP: + break; + case TGSI_OPCODE_ENDREP: + break; + case TGSI_OPCODE_PUSHA: + break; + case TGSI_OPCODE_POPA: + break; + case TGSI_OPCODE_CEIL: + break; + case TGSI_OPCODE_I2F: + break; + case TGSI_OPCODE_NOT: + break; + case TGSI_OPCODE_TRUNC: { + } + break; + case TGSI_OPCODE_SHL: + break; + case TGSI_OPCODE_SHR: + break; + case TGSI_OPCODE_AND: + break; + case TGSI_OPCODE_OR: + break; + case TGSI_OPCODE_MOD: + break; + case TGSI_OPCODE_XOR: + break; + case TGSI_OPCODE_SAD: + break; + case TGSI_OPCODE_TXF: + break; + case TGSI_OPCODE_TXQ: + break; + case TGSI_OPCODE_CONT: + break; + case TGSI_OPCODE_EMIT: + break; + case TGSI_OPCODE_ENDPRIM: + break; + case TGSI_OPCODE_BGNLOOP2: { + } + break; + case TGSI_OPCODE_BGNSUB: { + } + break; + case TGSI_OPCODE_ENDLOOP2: { + } + break; + case TGSI_OPCODE_ENDSUB: { + } + break; + case TGSI_OPCODE_NOISE1: + break; + case TGSI_OPCODE_NOISE2: + break; + case TGSI_OPCODE_NOISE3: + break; + case TGSI_OPCODE_NOISE4: + break; + case TGSI_OPCODE_NOP: + break; + case TGSI_OPCODE_TEXBEM: + break; + case TGSI_OPCODE_TEXBEML: + break; + case TGSI_OPCODE_TEXREG2AR: + break; + case TGSI_OPCODE_TEXM3X2PAD: + break; + case TGSI_OPCODE_TEXM3X2TEX: + break; + case TGSI_OPCODE_TEXM3X3PAD: + break; + case TGSI_OPCODE_TEXM3X3TEX: + break; + case TGSI_OPCODE_TEXM3X3SPEC: + break; + case TGSI_OPCODE_TEXM3X3VSPEC: + break; + case TGSI_OPCODE_TEXREG2GB: + break; + case TGSI_OPCODE_TEXREG2RGB: + break; + case TGSI_OPCODE_TEXDP3TEX: + break; + case TGSI_OPCODE_TEXDP3: + break; + case TGSI_OPCODE_TEXM3X3: + break; + case TGSI_OPCODE_TEXM3X2DEPTH: + break; + case TGSI_OPCODE_TEXDEPTH: + break; + case TGSI_OPCODE_BEM: + break; + case TGSI_OPCODE_M4X3: + break; + case TGSI_OPCODE_M3X4: + break; + case TGSI_OPCODE_M3X3: + break; + case TGSI_OPCODE_M3X2: + break; + case TGSI_OPCODE_NRM4: + break; + case TGSI_OPCODE_CALLNZ: + break; + case TGSI_OPCODE_IFC: + break; + case TGSI_OPCODE_BREAKC: + break; + case TGSI_OPCODE_KIL: + break; + case TGSI_OPCODE_END: + instr->end(); + return; + break; + default: + fprintf(stderr, "ERROR: Unknown opcode %d\n", + inst->Instruction.Opcode); + assert(0); + break; + } + + if (!out[0]) { + fprintf(stderr, "ERROR: unsupported opcode %d\n", + inst->Instruction.Opcode); + assert(!"Unsupported opcode"); + } + + /* store results */ + for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + + if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { + storage->store(StorageSoa::Output, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { + storage->store(StorageSoa::Temp, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { + storage->store(StorageSoa::Address, + dst->DstRegister.Index, out, dst->DstRegister.WriteMask); + } else { + fprintf(stderr, "ERROR: unsupported LLVM destination!"); + assert(!"wrong destination"); + } + } +} + +llvm::Module * +tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) +{ + llvm::Module *mod = new Module("shader"); + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned instno = 0; + Function* shader = mod->getFunction("execute_shader"); + std::ostringstream stream; + if (ir->type == GALLIVM_VS) { + stream << "vs_shader"; + } else { + stream << "fs_shader"; + } + stream << ir->id; + std::string func_name = stream.str(); + shader->setName(func_name.c_str()); + + Function::arg_iterator args = shader->arg_begin(); + Value *ptr_INPUT = args++; + ptr_INPUT->setName("input"); + + BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + + tgsi_parse_init(&parse, tokens); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + Storage storage(label_entry, ptr_INPUT); + Instructions instr(mod, shader, label_entry, &storage); + while(!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + translate_declaration(ir, mod, &storage, + &parse.FullToken.FullDeclaration, + &fd); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + translate_immediate(&storage, + &parse.FullToken.FullImmediate); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + translate_instruction(mod, &storage, &instr, + &parse.FullToken.FullInstruction, + &fi, instno); + ++instno; + break; + + default: + assert(0); + } + } + + tgsi_parse_free(&parse); + + ir->num_consts = storage.numConsts(); + return mod; +} + +llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, + const struct tgsi_token *tokens) +{ + llvm::Module *mod = new Module("shader"); + struct tgsi_parse_context parse; + struct tgsi_full_instruction fi; + struct tgsi_full_declaration fd; + unsigned instno = 0; + std::ostringstream stream; + if (ir->type == GALLIVM_VS) { + stream << "vs_shader"; + } else { + stream << "fs_shader"; + } + //stream << ir->id; + std::string func_name = stream.str(); + Function *shader = llvm::cast(mod->getOrInsertFunction( + func_name.c_str(), + vertexShaderFunctionType())); + + Function::arg_iterator args = shader->arg_begin(); + Value *input = args++; + input->setName("inputs"); + Value *output = args++; + output->setName("outputs"); + Value *consts = args++; + consts->setName("consts"); + Value *temps = args++; + temps->setName("temps"); + + BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + + tgsi_parse_init(&parse, tokens); + + fi = tgsi_default_full_instruction(); + fd = tgsi_default_full_declaration(); + + StorageSoa storage(label_entry, input, output, consts, temps); + InstructionsSoa instr(mod, shader, label_entry, &storage); + + while(!tgsi_parse_end_of_tokens(&parse)) { + tgsi_parse_token(&parse); + + switch (parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_DECLARATION: + translate_declarationir(ir, mod, &storage, + &parse.FullToken.FullDeclaration, + &fd); + break; + + case TGSI_TOKEN_TYPE_IMMEDIATE: + translate_immediateir(&storage, + &parse.FullToken.FullImmediate); + break; + + case TGSI_TOKEN_TYPE_INSTRUCTION: + storage.declareImmediates(); + translate_instructionir(mod, &storage, &instr, + &parse.FullToken.FullInstruction, + &fi, instno); + ++instno; + break; + + default: + assert(0); + } + } + + tgsi_parse_free(&parse); + + return mod; +} diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.h b/src/gallium/auxiliary/gallivm/tgsitollvm.h new file mode 100644 index 0000000000..7ada04d629 --- /dev/null +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.h @@ -0,0 +1,20 @@ +#ifndef TGSITOLLVM_H +#define TGSITOLLVM_H + + +namespace llvm { + class Module; +} + +struct gallivm_ir; +struct tgsi_token; + + +llvm::Module * tgsi_to_llvm(struct gallivm_ir *ir, + const struct tgsi_token *tokens); + + +llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, + const struct tgsi_token *tokens); + +#endif diff --git a/src/gallium/auxiliary/llvm/Makefile b/src/gallium/auxiliary/llvm/Makefile deleted file mode 100644 index 39fac6ea4a..0000000000 --- a/src/gallium/auxiliary/llvm/Makefile +++ /dev/null @@ -1,85 +0,0 @@ -# -*-makefile-*- -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = gallivm - - -GALLIVM_SOURCES = \ - gallivm.cpp \ - gallivm_cpu.cpp \ - instructions.cpp \ - loweringpass.cpp \ - tgsitollvm.cpp \ - storage.cpp \ - storagesoa.cpp \ - instructionssoa.cpp - -INC_SOURCES = gallivm_builtins.cpp - -CPP_SOURCES = \ - $(GALLIVM_SOURCES) - -C_SOURCES = -ASM_SOURCES = - -OBJECTS = $(C_SOURCES:.c=.o) \ - $(CPP_SOURCES:.cpp=.o) \ - $(ASM_SOURCES:.S=.o) - -### Include directories -INCLUDES = \ - -I. \ - -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/mesa \ - -I$(TOP)/include - - -##### RULES ##### - -.c.o: - $(CC) -c $(INCLUDES) $(LLVM_CFLAGS) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.cpp.o: - $(CXX) -c $(INCLUDES) $(LLVM_CXXFLAGS) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@ - -.S.o: - $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ - -##### TARGETS ##### - -default:: depend symlinks $(LIBNAME) - - -$(LIBNAME): $(OBJECTS) Makefile - $(TOP)/bin/mklib -o $@ -static $(OBJECTS) - - -depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) - rm -f depend - touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \ - $(ASM_SOURCES) $(INC_SOURCES) 2> /dev/null - - -gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins - - -# Emacs tags -tags: - etags `find . -name \*.[ch]` `find ../include` - - -# Remove .o and backup files -clean: - -rm -f *.o */*.o *~ *.so *~ server/*.o - -rm -f depend depend.bak - -rm -f gallivm_builtins.cpp - -symlinks: - - -include depend diff --git a/src/gallium/auxiliary/llvm/gallivm.cpp b/src/gallium/auxiliary/llvm/gallivm.cpp deleted file mode 100644 index d14bb3b99a..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "instructions.h" -#include "loweringpass.h" -#include "storage.h" -#include "tgsitollvm.h" - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static int GLOBAL_ID = 0; - -using namespace llvm; - -static inline -void AddStandardCompilePasses(PassManager &PM) -{ - PM.add(new LoweringPass()); - PM.add(createVerifierPass()); // Verify that input is correct - - PM.add(createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp - - //PM.add(createStripSymbolsPass(true)); - - PM.add(createRaiseAllocationsPass()); // call %malloc -> malloc inst - PM.add(createCFGSimplificationPass()); // Clean up disgusting code - PM.add(createPromoteMemoryToRegisterPass());// Kill useless allocas - PM.add(createGlobalOptimizerPass()); // Optimize out global vars - PM.add(createGlobalDCEPass()); // Remove unused fns and globs - PM.add(createIPConstantPropagationPass());// IP Constant Propagation - PM.add(createDeadArgEliminationPass()); // Dead argument elimination - PM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE - PM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - - PM.add(createPruneEHPass()); // Remove dead EH info - - PM.add(createFunctionInliningPass()); // Inline small functions - PM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args - - PM.add(createTailDuplicationPass()); // Simplify cfg by copying code - PM.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createScalarReplAggregatesPass()); // Break up aggregate allocas - PM.add(createInstructionCombiningPass()); // Combine silly seq's - PM.add(createCondPropagationPass()); // Propagate conditionals - - PM.add(createTailCallEliminationPass()); // Eliminate tail calls - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createReassociatePass()); // Reassociate expressions - PM.add(createLoopRotatePass()); - PM.add(createLICMPass()); // Hoist loop invariants - PM.add(createLoopUnswitchPass()); // Unswitch loops. - PM.add(createLoopIndexSplitPass()); // Index split loops. - PM.add(createInstructionCombiningPass()); // Clean up after LICM/reassoc - PM.add(createIndVarSimplifyPass()); // Canonicalize indvars - PM.add(createLoopUnrollPass()); // Unroll small loops - PM.add(createInstructionCombiningPass()); // Clean up after the unroller - PM.add(createGVNPass()); // Remove redundancies - PM.add(createSCCPPass()); // Constant prop with SCCP - - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - PM.add(createInstructionCombiningPass()); - PM.add(createCondPropagationPass()); // Propagate conditionals - - PM.add(createDeadStoreEliminationPass()); // Delete dead stores - PM.add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' - PM.add(createCFGSimplificationPass()); // Merge & remove BBs - PM.add(createSimplifyLibCallsPass()); // Library Call Optimizations - PM.add(createDeadTypeEliminationPass()); // Eliminate dead types - PM.add(createConstantMergePass()); // Merge dup global constants -} - -void gallivm_prog_delete(struct gallivm_prog *prog) -{ - delete prog->module; - prog->module = 0; - prog->function = 0; - free(prog); -} - -static inline void -constant_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan) -{ - unsigned i; - - for (i = 0; i < QUAD_SIZE; ++i) { - inputs[i][attrib][chan] = coefs[attrib].a0[chan]; - } -} - -static inline void -linear_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - const float x = inputs[i][0][0]; - const float y = inputs[i][0][1]; - - inputs[i][attrib][chan] = - coefs[attrib].a0[chan] + - coefs[attrib].dadx[chan] * x + - coefs[attrib].dady[chan] * y; - } -} - -static inline void -perspective_interpolation(float (*inputs)[16][4], - const struct tgsi_interp_coef *coefs, - unsigned attrib, - unsigned chan ) -{ - unsigned i; - - for( i = 0; i < QUAD_SIZE; i++ ) { - const float x = inputs[i][0][0]; - const float y = inputs[i][0][1]; - /* WPOS.w here is really 1/w */ - const float w = 1.0f / inputs[i][0][3]; - assert(inputs[i][0][3] != 0.0); - - inputs[i][attrib][chan] = - (coefs[attrib].a0[chan] + - coefs[attrib].dadx[chan] * x + - coefs[attrib].dady[chan] * y) * w; - } -} - -void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix) -{ - if (!ir || !ir->module) - return; - - if (file_prefix) { - std::ostringstream stream; - stream << file_prefix; - stream << ir->id; - stream << ".ll"; - std::string name = stream.str(); - std::ofstream out(name.c_str()); - if (!out) { - std::cerr<<"Can't open file : "<module); - out.close(); - } else { - const llvm::Module::FunctionListType &funcs = ir->module->getFunctionList(); - llvm::Module::FunctionListType::const_iterator itr; - std::cout<<"; ---------- Start shader "<id<id<num_interp; ++i) { - const gallivm_interpolate &interp = prog->interpolators[i]; - switch (interp.type) { - case TGSI_INTERPOLATE_CONSTANT: - constant_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - case TGSI_INTERPOLATE_LINEAR: - linear_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - case TGSI_INTERPOLATE_PERSPECTIVE: - perspective_interpolation(inputs, coef, interp.attrib, interp.chan); - break; - - default: - assert( 0 ); - } - } -} - - -struct gallivm_ir * gallivm_ir_new(enum gallivm_shader_type type) -{ - struct gallivm_ir *ir = - (struct gallivm_ir *)calloc(1, sizeof(struct gallivm_ir)); - ++GLOBAL_ID; - ir->id = GLOBAL_ID; - ir->type = type; - - return ir; -} - -void gallivm_ir_set_layout(struct gallivm_ir *ir, - enum gallivm_vector_layout layout) -{ - ir->layout = layout; -} - -void gallivm_ir_set_components(struct gallivm_ir *ir, int num) -{ - ir->num_components = num; -} - -void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, - const struct tgsi_token *tokens) -{ - std::cout << "Creating llvm from: " <module = mod; - gallivm_ir_dump(ir, 0); -} - -void gallivm_ir_delete(struct gallivm_ir *ir) -{ - delete ir->module; - free(ir); -} - -struct gallivm_prog * gallivm_ir_compile(struct gallivm_ir *ir) -{ - struct gallivm_prog *prog = - (struct gallivm_prog *)calloc(1, sizeof(struct gallivm_prog)); - llvm::Module *mod = llvm::CloneModule(ir->module); - prog->num_consts = ir->num_consts; - memcpy(prog->interpolators, ir->interpolators, sizeof(prog->interpolators)); - prog->num_interp = ir->num_interp; - - /* Run optimization passes over it */ - PassManager passes; - passes.add(new TargetData(mod)); - AddStandardCompilePasses(passes); - passes.run(*mod); - prog->module = mod; - - std::cout << "After optimizations:"<dump(); - - return prog; -} - -#endif /* MESA_LLVM */ diff --git a/src/gallium/auxiliary/llvm/gallivm.h b/src/gallium/auxiliary/llvm/gallivm.h deleted file mode 100644 index 92da4bca7f..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm.h +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef GALLIVM_H -#define GALLIVM_H - -#if defined __cplusplus -extern "C" { -#endif - -#include "pipe/p_state.h" - -#ifdef MESA_LLVM - -struct tgsi_token; - -struct gallivm_ir; -struct gallivm_prog; -struct gallivm_cpu_engine; -struct tgsi_interp_coef; -struct tgsi_sampler; -struct tgsi_exec_vector; - -enum gallivm_shader_type { - GALLIVM_VS, - GALLIVM_FS -}; - -enum gallivm_vector_layout { - GALLIVM_AOS, - GALLIVM_SOA -}; - -struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type); -void gallivm_ir_set_layout(struct gallivm_ir *ir, - enum gallivm_vector_layout layout); -void gallivm_ir_set_components(struct gallivm_ir *ir, int num); -void gallivm_ir_fill_from_tgsi(struct gallivm_ir *ir, - const struct tgsi_token *tokens); -void gallivm_ir_delete(struct gallivm_ir *ir); - - -struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir); - -void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog, - float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], - const struct tgsi_interp_coef *coefs); -void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix); - - -struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog); -struct gallivm_cpu_engine *gallivm_global_cpu_engine(); -int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_vector *inputs, - struct tgsi_exec_vector *dests, - float (*consts)[4], - struct tgsi_exec_vector *temps); -int gallivm_cpu_fs_exec(struct gallivm_prog *prog, - float x, float y, - float (*dests)[PIPE_MAX_SHADER_INPUTS][4], - float (*inputs)[PIPE_MAX_SHADER_INPUTS][4], - float (*consts)[4], - struct tgsi_sampler *samplers); -void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog); -void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee); - - -#endif /* MESA_LLVM */ - -#if defined __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/gallium/auxiliary/llvm/gallivm_builtins.cpp b/src/gallium/auxiliary/llvm/gallivm_builtins.cpp deleted file mode 100644 index 1796f0a177..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm_builtins.cpp +++ /dev/null @@ -1,567 +0,0 @@ -// Generated by llvm2cpp - DO NOT MODIFY! - - -Module* createGallivmBuiltins(Module *mod) { - -mod->setModuleIdentifier("shader"); - -// Type Definitions -ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); - -PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); - -std::vectorFuncTy_2_args; -FuncTy_2_args.push_back(Type::FloatTy); -FuncTy_2_args.push_back(Type::FloatTy); -FunctionType* FuncTy_2 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_2_args, - /*isVarArg=*/false); - -PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); - -VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); - -std::vectorFuncTy_5_args; -FuncTy_5_args.push_back(VectorTy_4); -FunctionType* FuncTy_5 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_5_args, - /*isVarArg=*/false); - -std::vectorFuncTy_6_args; -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FunctionType* FuncTy_6 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_6_args, - /*isVarArg=*/false); - -VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); - -std::vectorFuncTy_9_args; -FunctionType* FuncTy_9 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_9_args, - /*isVarArg=*/true); - -PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); - -PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); - -std::vectorFuncTy_12_args; -FuncTy_12_args.push_back(Type::FloatTy); -FunctionType* FuncTy_12 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_12_args, - /*isVarArg=*/false); - -PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); - -std::vectorFuncTy_13_args; -FuncTy_13_args.push_back(VectorTy_4); -FunctionType* FuncTy_13 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_13_args, - /*isVarArg=*/false); - - -// Function Declarations - -Function* func_approx = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"approx", mod); -func_approx->setCallingConv(CallingConv::C); -const ParamAttrsList *func_approx_PAL = 0; -func_approx->setParamAttrs(func_approx_PAL); - -Function* func_powf = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"powf", mod); // (external, no body) -func_powf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_powf_PAL = 0; -func_powf->setParamAttrs(func_powf_PAL); - -Function* func_lit = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"lit", mod); -func_lit->setCallingConv(CallingConv::C); -const ParamAttrsList *func_lit_PAL = 0; -func_lit->setParamAttrs(func_lit_PAL); - -Function* func_cmp = new Function( - /*Type=*/FuncTy_6, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"cmp", mod); -func_cmp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cmp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_cmp_PAL = ParamAttrsList::get(Attrs); - -} -func_cmp->setParamAttrs(func_cmp_PAL); - -Function* func_vcos = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vcos", mod); -func_vcos->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vcos_PAL = 0; -func_vcos->setParamAttrs(func_vcos_PAL); - -Function* func_printf = new Function( - /*Type=*/FuncTy_9, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", mod); // (external, no body) -func_printf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_printf_PAL = 0; -func_printf->setParamAttrs(func_printf_PAL); - -Function* func_cosf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"cosf", mod); // (external, no body) -func_cosf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cosf_PAL = 0; -func_cosf->setParamAttrs(func_cosf_PAL); - -Function* func_scs = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"scs", mod); -func_scs->setCallingConv(CallingConv::C); -const ParamAttrsList *func_scs_PAL = 0; -func_scs->setParamAttrs(func_scs_PAL); - -Function* func_sinf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"sinf", mod); // (external, no body) -func_sinf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_sinf_PAL = 0; -func_sinf->setParamAttrs(func_sinf_PAL); - -Function* func_vsin = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vsin", mod); -func_vsin->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vsin_PAL = 0; -func_vsin->setParamAttrs(func_vsin_PAL); - -Function* func_kilp = new Function( - /*Type=*/FuncTy_13, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"kilp", mod); -func_kilp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_kilp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_kilp_PAL = ParamAttrsList::get(Attrs); - -} -func_kilp->setParamAttrs(func_kilp_PAL); - -// Global Variable Declarations - - -GlobalVariable* gvar_array__str = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str", -mod); - -GlobalVariable* gvar_array__str1 = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str1", -mod); - -// Constant Definitions -Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); -Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); -ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); -ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); -Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); -Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); -std::vector const_packed_20_elems; -ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); -const_packed_20_elems.push_back(const_float_21); -UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_21); -Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); -ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); -ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); -ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); -std::vector const_packed_26_elems; -const_packed_26_elems.push_back(const_float_21); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_21); -Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); -Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); -std::vector const_packed_28_elems; -const_packed_28_elems.push_back(const_int32_19); -ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); -const_packed_28_elems.push_back(const_int32_29); -const_packed_28_elems.push_back(const_int32_25); -const_packed_28_elems.push_back(const_int32_24); -Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); -std::vector const_packed_30_elems; -const_packed_30_elems.push_back(const_int32_19); -const_packed_30_elems.push_back(const_int32_23); -ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); -const_packed_30_elems.push_back(const_int32_31); -const_packed_30_elems.push_back(const_int32_24); -Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); -std::vector const_packed_32_elems; -const_packed_32_elems.push_back(const_int32_19); -const_packed_32_elems.push_back(const_int32_23); -const_packed_32_elems.push_back(const_int32_25); -ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); -const_packed_32_elems.push_back(const_int32_33); -Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); -std::vector const_ptr_34_indices; -const_ptr_34_indices.push_back(const_int32_19); -const_ptr_34_indices.push_back(const_int32_19); -Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); -UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); -std::vector const_ptr_36_indices; -const_ptr_36_indices.push_back(const_int32_19); -const_ptr_36_indices.push_back(const_int32_19); -Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); - -// Global Variable Definitions -gvar_array__str->setInitializer(const_array_14); -gvar_array__str1->setInitializer(const_array_15); - -// Function Definitions - -// Function: approx (func_approx) -{ - Function::arg_iterator args = func_approx->arg_begin(); - Value* float_a = args++; - float_a->setName("a"); - Value* float_b = args++; - float_b->setName("b"); - - BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); - - // Block entry (label_entry) - FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); - SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); - FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); - SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); - FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); - SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); - std::vector float_call_params; - float_call_params.push_back(float_a_addr_0); - float_call_params.push_back(float_b_addr_1); - CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); - float_call->setCallingConv(CallingConv::C); - float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; - float_call->setParamAttrs(float_call_PAL); - - new ReturnInst(float_call, label_entry); - -} - -// Function: lit (func_lit) -{ - Function::arg_iterator args = func_lit->arg_begin(); - Value* packed_tmp = args++; - packed_tmp->setName("tmp"); - - BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); - BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); - BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); - - // Block entry (label_entry_38) - ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); - FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); - new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); - - // Block ifthen (label_ifthen) - InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); - ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); - ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); - std::vector float_call_41_params; - float_call_41_params.push_back(float_tmp12); - float_call_41_params.push_back(float_tmp14); - CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); - float_call_41->setCallingConv(CallingConv::C); - float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; - float_call_41->setParamAttrs(float_call_41_PAL); - - InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); - new ReturnInst(packed_tmp16, label_ifthen); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock) - new ReturnInst(const_packed_26, label_UnifiedReturnBlock); - -} - -// Function: cmp (func_cmp) -{ - Function::arg_iterator args = func_cmp->arg_begin(); - Value* packed_tmp0 = args++; - packed_tmp0->setName("tmp0"); - Value* packed_tmp1 = args++; - packed_tmp1->setName("tmp1"); - Value* packed_tmp2 = args++; - packed_tmp2->setName("tmp2"); - - BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); - BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); - BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); - BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); - BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); - BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); - BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); - - // Block entry (label_entry_44) - ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); - CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); - FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); - ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); - CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); - FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); - SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); - new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); - - // Block cond.?14 (label_cond__14) - ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); - ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); - CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); - FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); - - // Block cond.cont20 (label_cond_cont20) - ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); - ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); - CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); - FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); - - // Block cond.?28 (label_cond__28) - PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); - packed_tmp23_reg2mem_0->reserveOperandSpace(2); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); - ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); - CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); - FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); - - // Block cond.cont34 (label_cond_cont34) - PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); - packed_tmp23_reg2mem_1->reserveOperandSpace(2); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); - ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); - CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); - FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); - - // Block cond.?42 (label_cond__42) - PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); - packed_tmp37_reg2mem_0->reserveOperandSpace(2); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); - new ReturnInst(packed_tmp5113, label_cond__42); - - // Block cond.cont48 (label_cond_cont48) - PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); - packed_tmp37_reg2mem_1->reserveOperandSpace(2); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); - new ReturnInst(packed_tmp51, label_cond_cont48); - -} - -// Function: vcos (func_vcos) -{ - Function::arg_iterator args = func_vcos->arg_begin(); - Value* packed_val = args++; - packed_val->setName("val"); - - BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); - - // Block entry (label_entry_53) - ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); - CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); - ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); - CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); - ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); - CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); - ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); - CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); - std::vector int32_call_params; - int32_call_params.push_back(const_ptr_34); - int32_call_params.push_back(double_conv_54); - int32_call_params.push_back(double_conv4); - int32_call_params.push_back(double_conv7); - int32_call_params.push_back(double_conv10); - CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); - int32_call->setCallingConv(CallingConv::C); - int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; - int32_call->setParamAttrs(int32_call_PAL); - - CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); - float_call13->setCallingConv(CallingConv::C); - float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; - float_call13->setParamAttrs(float_call13_PAL); - - InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); - CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); - float_call18->setCallingConv(CallingConv::C); - float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; - float_call18->setParamAttrs(float_call18_PAL); - - InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); - CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); - float_call23->setCallingConv(CallingConv::C); - float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; - float_call23->setParamAttrs(float_call23_PAL); - - InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); - CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); - float_call28->setCallingConv(CallingConv::C); - float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; - float_call28->setParamAttrs(float_call28_PAL); - - InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); - CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); - CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); - CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); - CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); - std::vector int32_call43_params; - int32_call43_params.push_back(const_ptr_36); - int32_call43_params.push_back(double_conv33); - int32_call43_params.push_back(double_conv36); - int32_call43_params.push_back(double_conv39); - int32_call43_params.push_back(double_conv42); - CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); - int32_call43->setCallingConv(CallingConv::C); - int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; - int32_call43->setParamAttrs(int32_call43_PAL); - - new ReturnInst(packed_tmp30, label_entry_53); - -} - -// Function: scs (func_scs) -{ - Function::arg_iterator args = func_scs->arg_begin(); - Value* packed_val_58 = args++; - packed_val_58->setName("val"); - - BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); - - // Block entry (label_entry_59) - ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); - CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); - float_call_60->setCallingConv(CallingConv::C); - float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; - float_call_60->setParamAttrs(float_call_60_PAL); - - InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); - CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); - float_call7->setCallingConv(CallingConv::C); - float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; - float_call7->setParamAttrs(float_call7_PAL); - - InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); - new ReturnInst(packed_tmp9, label_entry_59); - -} - -// Function: vsin (func_vsin) -{ - Function::arg_iterator args = func_vsin->arg_begin(); - Value* packed_val_62 = args++; - packed_val_62->setName("val"); - - BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); - - // Block entry (label_entry_63) - ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); - CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); - float_call_65->setCallingConv(CallingConv::C); - float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; - float_call_65->setParamAttrs(float_call_65_PAL); - - InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); - InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); - InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); - InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); - new ReturnInst(packed_tmp15_67, label_entry_63); - -} - -// Function: kilp (func_kilp) -{ - Function::arg_iterator args = func_kilp->arg_begin(); - Value* packed_val_69 = args++; - packed_val_69->setName("val"); - - BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); - BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); - BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); - BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); - BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); - - // Block entry (label_entry_70) - ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); - FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); - - // Block lor_rhs (label_lor_rhs) - ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); - FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); - - // Block lor_rhs5 (label_lor_rhs5) - ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); - FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); - - // Block lor_rhs11 (label_lor_rhs11) - ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); - FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); - CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); - new ReturnInst(int32_retval, label_lor_rhs11); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) - new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); - -} - -return mod; - -} diff --git a/src/gallium/auxiliary/llvm/gallivm_cpu.cpp b/src/gallium/auxiliary/llvm/gallivm_cpu.cpp deleted file mode 100644 index 8f9830d0b1..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm_cpu.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "instructions.h" -#include "loweringpass.h" -#include "storage.h" -#include "tgsitollvm.h" - -#include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_dump.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -struct gallivm_cpu_engine { - llvm::ExecutionEngine *engine; -}; - -static struct gallivm_cpu_engine *CPU = 0; - -typedef int (*fragment_shader_runner)(float x, float y, - float (*dests)[16][4], - float (*inputs)[16][4], - int num_attribs, - float (*consts)[4], int num_consts, - struct tgsi_sampler *samplers); - -int gallivm_cpu_fs_exec(struct gallivm_prog *prog, - float fx, float fy, - float (*dests)[16][4], - float (*inputs)[16][4], - float (*consts)[4], - struct tgsi_sampler *samplers) -{ - fragment_shader_runner runner = reinterpret_cast(prog->function); - assert(runner); - - return runner(fx, fy, dests, inputs, prog->num_interp, - consts, prog->num_consts, - samplers); -} - -static inline llvm::Function *func_for_shader(struct gallivm_prog *prog) -{ - llvm::Module *mod = prog->module; - llvm::Function *func = 0; - - switch (prog->type) { - case GALLIVM_VS: - func = mod->getFunction("vs_shader"); - break; - case GALLIVM_FS: - func = mod->getFunction("fs_shader"); - break; - default: - assert(!"Unknown shader type!"); - break; - } - return func; -} - -/*! - This function creates a CPU based execution engine for the given gallivm_prog. - gallivm_cpu_engine should be used as a singleton throughout the library. Before - executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile. - The gallivm_prog instance which is being passed to the constructor is being - automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile - with it again. - */ -struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog) -{ - struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *) - calloc(1, sizeof(struct gallivm_cpu_engine)); - llvm::Module *mod = static_cast(prog->module); - llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); - llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false); - ee->DisableLazyCompilation(); - cpu->engine = ee; - - llvm::Function *func = func_for_shader(prog); - - prog->function = ee->getPointerToFunction(func); - CPU = cpu; - return cpu; -} - - -/*! - This function JIT compiles the given gallivm_prog with the given cpu based execution engine. - The reference to the generated machine code entry point will be stored - in the gallivm_prog program. After executing this function one can call gallivm_prog_exec - in order to execute the gallivm_prog on the CPU. - */ -void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog) -{ - llvm::Module *mod = static_cast(prog->module); - llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod); - llvm::ExecutionEngine *ee = cpu->engine; - assert(ee); - /*FIXME : remove */ - ee->DisableLazyCompilation(); - ee->addModuleProvider(mp); - - llvm::Function *func = func_for_shader(prog); - prog->function = ee->getPointerToFunction(func); -} - -void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu) -{ - free(cpu); -} - -struct gallivm_cpu_engine * gallivm_global_cpu_engine() -{ - return CPU; -} - - -typedef void (*vertex_shader_runner)(void *ainputs, - void *dests, - float (*aconsts)[4], - void *temps); - - -/*! - This function is used to execute the gallivm_prog in software. Before calling - this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile - function. - */ -int gallivm_cpu_vs_exec(struct gallivm_prog *prog, - struct tgsi_exec_vector *inputs, - struct tgsi_exec_vector *dests, - float (*consts)[4], - struct tgsi_exec_vector *temps) -{ - vertex_shader_runner runner = reinterpret_cast(prog->function); - assert(runner); - /*FIXME*/ - runner(inputs, dests, consts, temps); - - return 0; -} - -#endif diff --git a/src/gallium/auxiliary/llvm/gallivm_p.h b/src/gallium/auxiliary/llvm/gallivm_p.h deleted file mode 100644 index cfe7b1901b..0000000000 --- a/src/gallium/auxiliary/llvm/gallivm_p.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef GALLIVM_P_H -#define GALLIVM_P_H - -#ifdef MESA_LLVM - -#include "gallivm.h" -#include "pipe/p_shader_tokens.h" -#include "pipe/p_compiler.h" - -namespace llvm { - class Module; -} - -#if defined __cplusplus -extern "C" { -#endif - -enum gallivm_shader_type; -enum gallivm_vector_layout; - -struct gallivm_interpolate { - int attrib; - int chan; - int type; -}; - -struct gallivm_ir { - llvm::Module *module; - int id; - enum gallivm_shader_type type; - enum gallivm_vector_layout layout; - int num_components; - int num_consts; - - //FIXME: this might not be enough for some shaders - struct gallivm_interpolate interpolators[32*4]; - int num_interp; -}; - -struct gallivm_prog { - llvm::Module *module; - void *function; - - int id; - enum gallivm_shader_type type; - - int num_consts; - - //FIXME: this might not be enough for some shaders - struct gallivm_interpolate interpolators[32*4]; - int num_interp; -}; - -static INLINE void gallivm_swizzle_components(int swizzle, - int *xc, int *yc, - int *zc, int *wc) -{ - int x = swizzle / 1000; swizzle -= x * 1000; - int y = swizzle / 100; swizzle -= y * 100; - int z = swizzle / 10; swizzle -= z * 10; - int w = swizzle; - - if (xc) *xc = x; - if (yc) *yc = y; - if (zc) *zc = z; - if (wc) *wc = w; -} - -static INLINE boolean gallivm_is_swizzle(int swizzle) -{ - const int NO_SWIZZLE = TGSI_SWIZZLE_X * 1000 + TGSI_SWIZZLE_Y * 100 + - TGSI_SWIZZLE_Z * 10 + TGSI_SWIZZLE_W; - return swizzle != NO_SWIZZLE; -} - -static INLINE int gallivm_x_swizzle(int swizzle) -{ - int x; - gallivm_swizzle_components(swizzle, &x, 0, 0, 0); - return x; -} - -static INLINE int gallivm_y_swizzle(int swizzle) -{ - int y; - gallivm_swizzle_components(swizzle, 0, &y, 0, 0); - return y; -} - -static INLINE int gallivm_z_swizzle(int swizzle) -{ - int z; - gallivm_swizzle_components(swizzle, 0, 0, &z, 0); - return z; -} - -static INLINE int gallivm_w_swizzle(int swizzle) -{ - int w; - gallivm_swizzle_components(swizzle, 0, 0, 0, &w); - return w; -} - -#endif /* MESA_LLVM */ - -#if defined __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/gallium/auxiliary/llvm/instructions.cpp b/src/gallium/auxiliary/llvm/instructions.cpp deleted file mode 100644 index 55d39fa5f1..0000000000 --- a/src/gallium/auxiliary/llvm/instructions.cpp +++ /dev/null @@ -1,889 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "instructions.h" - -#include "storage.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -using namespace llvm; - -#include "gallivm_builtins.cpp" - -static inline std::string createFuncName(int label) -{ - std::ostringstream stream; - stream << "function"; - stream << label; - return stream.str(); -} - -Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, - Storage *storage) - : m_mod(mod), m_func(func), m_builder(block), m_idx(0), - m_storage(storage) -{ - m_floatVecType = VectorType::get(Type::FloatTy, 4); - - m_llvmFSqrt = 0; - m_llvmFAbs = 0; - m_llvmPow = 0; - m_llvmFloor = 0; - m_llvmFlog = 0; - m_llvmLit = 0; - m_fmtPtr = 0; - - createGallivmBuiltins(m_mod); -} - -llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateAdd(in1, in2, name("add")); -} - -llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3) -{ - Value *mulRes = mul(in1, in2); - return add(mulRes, in3); -} - -llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2) -{ - return m_builder.CreateMul(in1, in2, name("mul")); -} - -const char * Instructions::name(const char *prefix) -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - Value *x = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(0), - name("extractx")); - Value *y = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(1), - name("extracty")); - Value *z = m_builder.CreateExtractElement(mulRes, - m_storage->constantInt(2), - name("extractz")); - Value *xy = m_builder.CreateAdd(x, y,name("xy")); - Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3")); - return vectorFromVals(dot3, dot3, dot3, dot3); -} - -llvm::Value *Instructions::callFSqrt(llvm::Value *val) -{ - if (!m_llvmFSqrt) { - // predeclare the intrinsic - std::vector fsqrtArgs; - fsqrtArgs.push_back(Type::FloatTy); - ParamAttrsList *fsqrtPal = 0; - FunctionType* fsqrtType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fsqrtArgs, - /*isVarArg=*/false); - m_llvmFSqrt = new Function( - /*Type=*/fsqrtType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"llvm.sqrt.f32", m_mod); - m_llvmFSqrt->setCallingConv(CallingConv::C); - m_llvmFSqrt->setParamAttrs(fsqrtPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val, - name("sqrt")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::rsq(llvm::Value *in1) -{ - Value *x = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("extractx")); - Value *abs = callFAbs(x); - Value *sqrt = callFSqrt(abs); - - Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, - APFloat(1.f)), - sqrt, - name("rsqrt")); - return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt); -} - -llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w) -{ - Constant *const_vec = Constant::getNullValue(m_floatVecType); - Value *res = m_builder.CreateInsertElement(const_vec, x, - m_storage->constantInt(0), - name("vecx")); - res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), - name("vecxy")); - res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), - name("vecxyz")); - if (w) - res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), - name("vecxyzw")); - return res; -} - -llvm::Value *Instructions::callFAbs(llvm::Value *val) -{ - if (!m_llvmFAbs) { - // predeclare the intrinsic - std::vector fabsArgs; - fabsArgs.push_back(Type::FloatTy); - ParamAttrsList *fabsPal = 0; - FunctionType* fabsType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/fabsArgs, - /*isVarArg=*/false); - m_llvmFAbs = new Function( - /*Type=*/fabsType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"fabs", m_mod); - m_llvmFAbs->setCallingConv(CallingConv::C); - m_llvmFAbs->setParamAttrs(fabsPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFAbs, val, - name("fabs")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::lit(llvm::Value *in) -{ - if (!m_llvmLit) { - m_llvmLit = m_mod->getFunction("lit"); - } - CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2) -{ - Value *res = m_builder.CreateSub(in1, in2, name("sub")); - return res; -} - -llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) -{ - if (!m_llvmPow) { - // predeclare the intrinsic - std::vector powArgs; - powArgs.push_back(Type::FloatTy); - powArgs.push_back(Type::FloatTy); - ParamAttrsList *powPal = 0; - FunctionType* powType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/powArgs, - /*isVarArg=*/false); - m_llvmPow = new Function( - /*Type=*/powType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"llvm.pow.f32", m_mod); - m_llvmPow->setCallingConv(CallingConv::C); - m_llvmPow->setParamAttrs(powPal); - } - std::vector params; - params.push_back(val1); - params.push_back(val2); - CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(), - name("pow")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *x2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(0), - name("x2")); - llvm::Value *val = callPow(x1, x2); - return vectorFromVals(val, val, val, val); -} - -llvm::Value * Instructions::rcp(llvm::Value *in1) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *res = m_builder.CreateFDiv(ConstantFP::get(Type::FloatTy, - APFloat(1.f)), - x1, name("rcp")); - return vectorFromVals(res, res, res, res); -} - -llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - std::vector vec = extractVector(mulRes); - Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy")); - Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz")); - Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4")); - return vectorFromVals(dot4, dot4, dot4, dot4); -} - -llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2) -{ - Value *mulRes = mul(in1, in2); - std::vector vec1 = extractVector(mulRes); - Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy")); - Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz")); - Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph")); - return vectorFromVals(dph, dph, dph, dph); -} - -llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2) -{ - Value *y1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(1), - name("y1")); - Value *z = m_builder.CreateExtractElement(in1, - m_storage->constantInt(2), - name("z")); - Value *y2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(1), - name("y2")); - Value *w = m_builder.CreateExtractElement(in2, - m_storage->constantInt(3), - name("w")); - Value *ry = m_builder.CreateMul(y1, y2, name("tyuy")); - return vectorFromVals(ConstantFP::get(Type::FloatTy, APFloat(1.f)), - ry, z, w); -} - -llvm::Value * Instructions::ex2(llvm::Value *in) -{ - llvm::Value *val = callPow(ConstantFP::get(Type::FloatTy, APFloat(2.f)), - m_builder.CreateExtractElement( - in, m_storage->constantInt(0), - name("x1"))); - return vectorFromVals(val, val, val, val); -} - -llvm::Value * Instructions::callFloor(llvm::Value *val) -{ - if (!m_llvmFloor) { - // predeclare the intrinsic - std::vector floorArgs; - floorArgs.push_back(Type::FloatTy); - ParamAttrsList *floorPal = 0; - FunctionType* floorType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/floorArgs, - /*isVarArg=*/false); - m_llvmFloor = new Function( - /*Type=*/floorType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"floorf", m_mod); - m_llvmFloor->setCallingConv(CallingConv::C); - m_llvmFloor->setParamAttrs(floorPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFloor, val, - name("floorf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::floor(llvm::Value *in) -{ - std::vector vec = extractVector(in); - return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]), - callFloor(vec[2]), callFloor(vec[3])); -} - -llvm::Value * Instructions::arl(llvm::Value *in) -{ - return floor(in); -} - -llvm::Value * Instructions::frc(llvm::Value *in) -{ - llvm::Value *flr = floor(in); - return sub(in, flr); -} - -llvm::Value * Instructions::callFLog(llvm::Value *val) -{ - if (!m_llvmFlog) { - // predeclare the intrinsic - std::vector flogArgs; - flogArgs.push_back(Type::FloatTy); - ParamAttrsList *flogPal = 0; - FunctionType* flogType = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/flogArgs, - /*isVarArg=*/false); - m_llvmFlog = new Function( - /*Type=*/flogType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"logf", m_mod); - m_llvmFlog->setCallingConv(CallingConv::C); - m_llvmFlog->setParamAttrs(flogPal); - } - CallInst *call = m_builder.CreateCall(m_llvmFlog, val, - name("logf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::lg2(llvm::Value *in) -{ - std::vector vec = extractVector(in); - llvm::Value *const_vec = constVector(1.442695f, 1.442695f, - 1.442695f, 1.442695f); - return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]), - callFLog(vec[2]), callFLog(vec[3])), const_vec); -} - -llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2) -{ - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2) -{ - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], - name("xcmp")); - Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0], - name("selx")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], - name("ycmp")); - Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1], - name("sely")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], - name("zcmp")); - Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2], - name("selz")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], - name("wcmp")); - Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3], - name("selw")); - - return vectorFromVals(selx, sely, selz, selw); -} - -void Instructions::printVector(llvm::Value *val) -{ - static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A"; - - if (!m_fmtPtr) { - Constant *format = ConstantArray::get(frmt, true); - ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1); - GlobalVariable* globalFormat = new GlobalVariable( - /*Type=*/arrayTy, - /*isConstant=*/true, - /*Linkage=*/GlobalValue::InternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name(".str"), - m_mod); - globalFormat->setInitializer(format); - - Constant* const_int0 = Constant::getNullValue(IntegerType::get(32)); - std::vector const_ptr_21_indices; - const_ptr_21_indices.push_back(const_int0); - const_ptr_21_indices.push_back(const_int0); - m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat, - &const_ptr_21_indices[0], const_ptr_21_indices.size()); - } - - Function *func_printf = m_mod->getFunction("printf"); - if (!func_printf) - func_printf = declarePrintf(); - assert(func_printf); - std::vector vec = extractVector(val); - Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx")); - Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy")); - Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz")); - Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw")); - std::vector params; - params.push_back(m_fmtPtr); - params.push_back(dx); - params.push_back(dy); - params.push_back(dz); - params.push_back(dw); - CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(), - name("printf")); - call->setCallingConv(CallingConv::C); - call->setTailCall(true); -} - -llvm::Function * Instructions::declarePrintf() -{ - std::vector args; - ParamAttrsList *params = 0; - FunctionType* funcTy = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/args, - /*isVarArg=*/true); - Function* func_printf = new Function( - /*Type=*/funcTy, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", m_mod); - func_printf->setCallingConv(CallingConv::C); - func_printf->setParamAttrs(params); - return func_printf; -} - - -llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} -llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - - -llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2) -{ - Constant *const1f = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); - Constant *const0f = Constant::getNullValue(Type::FloatTy); - - std::vector vec1 = extractVector(in1); - std::vector vec2 = extractVector(in2); - - Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp")); - Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel")); - - Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp")); - Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel")); - - Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp")); - Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel")); - - Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp")); - Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel")); - - return vectorFromVals(x, y, z, w); -} - -llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2) -{ - Value *x1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(0), - name("x1")); - Value *y1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(1), - name("y1")); - Value *z1 = m_builder.CreateExtractElement(in1, - m_storage->constantInt(2), - name("z1")); - - Value *x2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(0), - name("x2")); - Value *y2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(1), - name("y2")); - Value *z2 = m_builder.CreateExtractElement(in2, - m_storage->constantInt(2), - name("z2")); - Value *y1z2 = mul(y1, z2); - Value *z1y2 = mul(z1, y2); - - Value *z1x2 = mul(z1, x2); - Value *x1z2 = mul(x1, z2); - - Value *x1y2 = mul(x1, y2); - Value *y1x2 = mul(y1, x2); - - return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2)); -} - - -llvm::Value * Instructions::abs(llvm::Value *in) -{ - std::vector vec = extractVector(in); - Value *xabs = callFAbs(vec[0]); - Value *yabs = callFAbs(vec[1]); - Value *zabs = callFAbs(vec[2]); - Value *wabs = callFAbs(vec[3]); - return vectorFromVals(xabs, yabs, zabs, wabs); -} - -void Instructions::ifop(llvm::Value *in) -{ - BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); - BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); - - //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); - //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); - //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0); - - Constant *float0 = Constant::getNullValue(Type::FloatTy); - - Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0), - name("extractx")); - Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp")); - m_builder.CreateCondBr(xcmp, ifthen, ifend); - //m_builder.SetInsertPoint(yblock); - - m_builder.SetInsertPoint(ifthen); - m_ifStack.push(ifend); -} - -llvm::BasicBlock * Instructions::currentBlock() const -{ - return m_builder.GetInsertBlock(); -} - -void Instructions::elseop() -{ - assert(!m_ifStack.empty()); - BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); - m_builder.CreateBr(ifend); - m_builder.SetInsertPoint(m_ifStack.top()); - currentBlock()->setName(name("ifelse")); - m_ifStack.pop(); - m_ifStack.push(ifend); -} - -void Instructions::endif() -{ - assert(!m_ifStack.empty()); - m_builder.CreateBr(m_ifStack.top()); - m_builder.SetInsertPoint(m_ifStack.top()); - m_ifStack.pop(); -} - -llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3) -{ - llvm::Value *m = mul(in1, in2); - llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f); - llvm::Value *s = sub(vec1, in1); - return add(m, mul(s, in3)); -} - -void Instructions::beginLoop() -{ - BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); - BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); - - m_builder.CreateBr(begin); - Loop loop; - loop.begin = begin; - loop.end = end; - m_builder.SetInsertPoint(begin); - m_loopStack.push(loop); -} - -void Instructions::endLoop() -{ - assert(!m_loopStack.empty()); - Loop loop = m_loopStack.top(); - m_builder.CreateBr(loop.begin); - loop.end->moveAfter(currentBlock()); - m_builder.SetInsertPoint(loop.end); - m_loopStack.pop(); -} - -void Instructions::brk() -{ - assert(!m_loopStack.empty()); - BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); - m_builder.CreateBr(m_loopStack.top().end); - m_builder.SetInsertPoint(unr); -} - -llvm::Value * Instructions::trunc(llvm::Value *in) -{ - std::vector vec = extractVector(in); - Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32), - name("ftoix")); - Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32), - name("ftoiy")); - Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32), - name("ftoiz")); - Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32), - name("ftoiw")); - Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy, - name("fx")); - Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy, - name("fy")); - Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy, - name("fz")); - Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy, - name("fw")); - return vectorFromVals(fx, fy, fz, fw); -} - -void Instructions::end() -{ - m_builder.CreateRetVoid(); -} - -void Instructions::cal(int label, llvm::Value *input) -{ - std::vector params; - params.push_back(input); - llvm::Function *func = findFunction(label); - - m_builder.CreateCall(func, params.begin(), params.end()); -} - -llvm::Function * Instructions::declareFunc(int label) -{ - PointerType *vecPtr = PointerType::getUnqual(m_floatVecType); - std::vector args; - args.push_back(vecPtr); - args.push_back(vecPtr); - args.push_back(vecPtr); - args.push_back(vecPtr); - ParamAttrsList *params = 0; - FunctionType *funcType = FunctionType::get( - /*Result=*/Type::VoidTy, - /*Params=*/args, - /*isVarArg=*/false); - std::string name = createFuncName(label); - Function *func = new Function( - /*Type=*/funcType, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/name.c_str(), m_mod); - func->setCallingConv(CallingConv::C); - func->setParamAttrs(params); - return func; -} - -void Instructions::bgnSub(unsigned label) -{ - llvm::Function *func = findFunction(label); - - Function::arg_iterator args = func->arg_begin(); - Value *ptr_INPUT = args++; - ptr_INPUT->setName("INPUT"); - m_storage->pushArguments(ptr_INPUT); - - llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); - - m_func = func; - m_builder.SetInsertPoint(entry); -} - -void Instructions::endSub() -{ - m_func = 0; - m_builder.SetInsertPoint(0); -} - -llvm::Function * Instructions::findFunction(int label) -{ - llvm::Function *func = m_functions[label]; - if (!func) { - func = declareFunc(label); - m_functions[label] = func; - } - return func; -} - -llvm::Value * Instructions::constVector(float x, float y, float z, float w) -{ - std::vector vec(4); - vec[0] = ConstantFP::get(Type::FloatTy, APFloat(x)); - vec[1] = ConstantFP::get(Type::FloatTy, APFloat(y)); - vec[2] = ConstantFP::get(Type::FloatTy, APFloat(z)); - vec[3] = ConstantFP::get(Type::FloatTy, APFloat(w)); - return ConstantVector::get(m_floatVecType, vec); -} - - -std::vector Instructions::extractVector(llvm::Value *vec) -{ - std::vector elems(4); - elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0), - name("x")); - elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1), - name("y")); - elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2), - name("z")); - elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3), - name("w")); - return elems; -} - -llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3) -{ - llvm::Function *func = m_mod->getFunction("cmp"); - assert(func); - - std::vector params; - params.push_back(in1); - params.push_back(in2); - params.push_back(in3); - CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::cos(llvm::Value *in) -{ -#if 0 - llvm::Function *func = m_mod->getFunction("vcos"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("cosres")); - call->setTailCall(false); - return call; -#else - std::vector elems = extractVector(in); - Function *func = m_mod->getFunction("cosf"); - assert(func); - CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres")); - cos->setCallingConv(CallingConv::C); - cos->setTailCall(true); - return vectorFromVals(cos, cos, cos, cos); -#endif -} - -llvm::Value * Instructions::scs(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("scs"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("scsres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::kilp(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("kilp"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("kilpres")); - call->setTailCall(false); - return call; -} - -llvm::Value * Instructions::sin(llvm::Value *in) -{ - llvm::Function *func = m_mod->getFunction("vsin"); - assert(func); - - CallInst *call = m_builder.CreateCall(func, in, name("sinres")); - call->setTailCall(false); - return call; -} -#endif //MESA_LLVM - - diff --git a/src/gallium/auxiliary/llvm/instructions.h b/src/gallium/auxiliary/llvm/instructions.h deleted file mode 100644 index 9ebc17dd8e..0000000000 --- a/src/gallium/auxiliary/llvm/instructions.h +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef INSTRUCTIONS_H -#define INSTRUCTIONS_H - -#include -#include -#include -#include - -#include -#include - -namespace llvm { - class VectorType; - class Function; -} - -class Storage; - -class Instructions -{ -public: - Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block, - Storage *storage); - - llvm::BasicBlock *currentBlock() const; - - llvm::Value *abs(llvm::Value *in1); - llvm::Value *arl(llvm::Value *in1); - llvm::Value *add(llvm::Value *in1, llvm::Value *in2); - void beginLoop(); - void bgnSub(unsigned); - void brk(); - void cal(int label, llvm::Value *input); - llvm::Value *cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3); - llvm::Value *cos(llvm::Value *in); - llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); - llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); - void elseop(); - void endif(); - void endLoop(); - void end(); - void endSub(); - llvm::Value *ex2(llvm::Value *in); - llvm::Value *floor(llvm::Value *in); - llvm::Value *frc(llvm::Value *in); - void ifop(llvm::Value *in); - llvm::Value *kilp(llvm::Value *in); - llvm::Value *lerp(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in3); - llvm::Value *lit(llvm::Value *in); - llvm::Value *lg2(llvm::Value *in); - llvm::Value *madd(llvm::Value *in1, llvm::Value *in2, - llvm::Value *in2); - llvm::Value *min(llvm::Value *in1, llvm::Value *in2); - llvm::Value *max(llvm::Value *in1, llvm::Value *in2); - llvm::Value *mul(llvm::Value *in1, llvm::Value *in2); - llvm::Value *pow(llvm::Value *in1, llvm::Value *in2); - llvm::Value *rcp(llvm::Value *in); - llvm::Value *rsq(llvm::Value *in); - llvm::Value *scs(llvm::Value *in); - llvm::Value *sge(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sin(llvm::Value *in); - llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); - llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); - llvm::Value *trunc(llvm::Value *in); - - void printVector(llvm::Value *val); -private: - const char *name(const char *prefix); - - llvm::Value *callFAbs(llvm::Value *val); - llvm::Value *callFloor(llvm::Value *val); - llvm::Value *callFSqrt(llvm::Value *val); - llvm::Value *callFLog(llvm::Value *val); - llvm::Value *callPow(llvm::Value *val1, llvm::Value *val2); - - llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w=0); - - llvm::Value *constVector(float x, float y, float z, float w); - - llvm::Function *declarePrintf(); - llvm::Function *declareFunc(int label); - - llvm::Function *findFunction(int label); - - std::vector extractVector(llvm::Value *vec); -private: - llvm::Module *m_mod; - llvm::Function *m_func; - char m_name[32]; - llvm::LLVMFoldingBuilder m_builder; - int m_idx; - - llvm::VectorType *m_floatVecType; - - llvm::Function *m_llvmFSqrt; - llvm::Function *m_llvmFAbs; - llvm::Function *m_llvmPow; - llvm::Function *m_llvmFloor; - llvm::Function *m_llvmFlog; - llvm::Function *m_llvmLit; - - llvm::Constant *m_fmtPtr; - - std::stack m_ifStack; - struct Loop { - llvm::BasicBlock *begin; - llvm::BasicBlock *end; - }; - std::stack m_loopStack; - std::map m_functions; - Storage *m_storage; -}; - -#endif diff --git a/src/gallium/auxiliary/llvm/instructionssoa.cpp b/src/gallium/auxiliary/llvm/instructionssoa.cpp deleted file mode 100644 index a4d5046637..0000000000 --- a/src/gallium/auxiliary/llvm/instructionssoa.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "instructionssoa.h" - -#include "storagesoa.h" - -#include - -using namespace llvm; - -InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, - llvm::BasicBlock *block, StorageSoa *storage) - : m_builder(block), - m_storage(storage), - m_idx(0) -{ -} - -const char * InstructionsSoa::name(const char *prefix) const -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - Constant *constVector = Constant::getNullValue(vectorType); - Value *res = m_builder.CreateInsertElement(constVector, x, - m_storage->constantInt(0), - name("vecx")); - res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), - name("vecxy")); - res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), - name("vecxyz")); - if (w) - res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), - name("vecxyzw")); - return res; -} - -std::vector InstructionsSoa::arl(const std::vector in) -{ - std::vector res(4); - - //Extract x's - llvm::Value *x1 = m_builder.CreateExtractElement(in[0], - m_storage->constantInt(0), - name("extractX")); - //cast it to an unsigned int - x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); - - res[0] = x1;//vectorFromVals(x1, x2, x3, x4); - //only x is valid. the others shouldn't be necessary - /* - res[1] = Constant::getNullValue(m_floatVecType); - res[2] = Constant::getNullValue(m_floatVecType); - res[3] = Constant::getNullValue(m_floatVecType); - */ - - return res; -} - - -std::vector InstructionsSoa::add(const std::vector in1, - const std::vector in2) -{ - std::vector res(4); - - res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); - res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); - res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); - res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); - - return res; -} - -std::vector InstructionsSoa::mul(const std::vector in1, - const std::vector in2) -{ - std::vector res(4); - - res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); - res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); - res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); - res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); - - return res; -} - -void InstructionsSoa::end() -{ - m_builder.CreateRetVoid(); -} - -std::vector InstructionsSoa::madd(const std::vector in1, - const std::vector in2, - const std::vector in3) -{ - std::vector res = mul(in1, in2); - return add(res, in3); -} - -std::vector InstructionsSoa::extractVector(llvm::Value *vector) -{ - std::vector res(4); - res[0] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(0), - name("extract1X")); - res[1] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(1), - name("extract2X")); - res[2] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(2), - name("extract3X")); - res[3] = m_builder.CreateExtractElement(vector, - m_storage->constantInt(3), - name("extract4X")); - - return res; -} diff --git a/src/gallium/auxiliary/llvm/instructionssoa.h b/src/gallium/auxiliary/llvm/instructionssoa.h deleted file mode 100644 index 4169dcbb2e..0000000000 --- a/src/gallium/auxiliary/llvm/instructionssoa.h +++ /dev/null @@ -1,74 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INSTRUCTIONSSOA_H -#define INSTRUCTIONSSOA_H - -#include - -#include - -namespace llvm { - class Module; - class Function; - class BasicBlock; - class Value; -} -class StorageSoa; - -class InstructionsSoa -{ -public: - InstructionsSoa(llvm::Module *mod, llvm::Function *func, - llvm::BasicBlock *block, StorageSoa *storage); - - std::vector arl(const std::vector in); - - std::vector add(const std::vector in1, - const std::vector in2); - std::vector madd(const std::vector in1, - const std::vector in2, - const std::vector in3); - std::vector mul(const std::vector in1, - const std::vector in2); - void end(); - - std::vector extractVector(llvm::Value *vector); -private: - const char * name(const char *prefix) const; - llvm::Value *vectorFromVals(llvm::Value *x, llvm::Value *y, - llvm::Value *z, llvm::Value *w); -private: - llvm::LLVMFoldingBuilder m_builder; - StorageSoa *m_storage; -private: - mutable int m_idx; - mutable char m_name[32]; -}; - - -#endif diff --git a/src/gallium/auxiliary/llvm/llvm_builtins.c b/src/gallium/auxiliary/llvm/llvm_builtins.c deleted file mode 100644 index 4f98d754ba..0000000000 --- a/src/gallium/auxiliary/llvm/llvm_builtins.c +++ /dev/null @@ -1,115 +0,0 @@ -/*clang --emit-llvm llvm_builtins.c |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=gallivm_builtins.cpp -f -for=shader -funcname=createGallivmBuiltins*/ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -typedef __attribute__(( ocu_vector_type(4) )) float float4; - -extern float powf(float a, float b); - -inline float approx(float a, float b) -{ - if (b < -128.0f) b = -128.0f; - if (b > 128.0f) b = 128.0f; - if (a < 0) a = 0; - return powf(a, b); -} - -inline float4 lit(float4 tmp) -{ - float4 result; - result.x = 1.0; - result.w = 1.0; - if (tmp.x > 0) { - result.y = tmp.x; - result.z = approx(tmp.y, tmp.w); - } else { - result.y = 0; - result.z = 0; - } - return result; -} - -inline float4 cmp(float4 tmp0, float4 tmp1, float4 tmp2) -{ - float4 result; - - result.x = (tmp0.x < 0.0) ? tmp1.x : tmp2.x; - result.y = (tmp0.y < 0.0) ? tmp1.y : tmp2.y; - result.z = (tmp0.z < 0.0) ? tmp1.z : tmp2.z; - result.w = (tmp0.w < 0.0) ? tmp1.w : tmp2.w; - - return result; -} - -extern float cosf(float val); -extern float sinf(float val); - -inline float4 vcos(float4 val) -{ - float4 result; - printf("VEC IN is %f %f %f %f\n", val.x, val.y, val.z, val.w); - result.x = cosf(val.x); - result.y = cosf(val.x); - result.z = cosf(val.x); - result.w = cosf(val.x); - printf("VEC OUT is %f %f %f %f\n", result.x, result.y, result.z, result.w); - return result; -} - -inline float4 scs(float4 val) -{ - float4 result; - float tmp = val.x; - result.x = cosf(tmp); - result.y = sinf(tmp); - return result; -} - - -inline float4 vsin(float4 val) -{ - float4 result; - float tmp = val.x; - float res = sinf(tmp); - result.x = res; - result.y = res; - result.z = res; - result.w = res; - return result; -} - -inline int kilp(float4 val) -{ - if (val.x < 0 || val.y < 0 || val.z < 0 || val.w < 0) - return 1; - else - return 0; -} diff --git a/src/gallium/auxiliary/llvm/loweringpass.cpp b/src/gallium/auxiliary/llvm/loweringpass.cpp deleted file mode 100644 index 556dbec366..0000000000 --- a/src/gallium/auxiliary/llvm/loweringpass.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "loweringpass.h" - -using namespace llvm; - -char LoweringPass::ID = 0; -RegisterPass X("lowering", "Lowering Pass"); - -LoweringPass::LoweringPass() - : ModulePass((intptr_t)&ID) -{ -} - -bool LoweringPass::runOnModule(Module &m) -{ - llvm::cerr << "Hello: " << m.getModuleIdentifier() << "\n"; - return false; -} diff --git a/src/gallium/auxiliary/llvm/loweringpass.h b/src/gallium/auxiliary/llvm/loweringpass.h deleted file mode 100644 index f62dcf6ba7..0000000000 --- a/src/gallium/auxiliary/llvm/loweringpass.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef LOWERINGPASS_H -#define LOWERINGPASS_H - -#include "llvm/Pass.h" -#include "llvm/Module.h" - -struct LoweringPass : public llvm::ModulePass -{ - static char ID; - LoweringPass(); - - virtual bool runOnModule(llvm::Module &m); -}; - -#endif diff --git a/src/gallium/auxiliary/llvm/storage.cpp b/src/gallium/auxiliary/llvm/storage.cpp deleted file mode 100644 index c4326de8c5..0000000000 --- a/src/gallium/auxiliary/llvm/storage.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ -#ifdef MESA_LLVM - -#include "storage.h" - -#include "gallivm_p.h" - -#include "pipe/p_shader_tokens.h" -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace llvm; - -Storage::Storage(llvm::BasicBlock *block, llvm::Value *input) - : m_block(block), - m_INPUT(input), - m_addrs(32), - m_idx(0) -{ - m_floatVecType = VectorType::get(Type::FloatTy, 4); - m_intVecType = VectorType::get(IntegerType::get(32), 4); - - m_undefFloatVec = UndefValue::get(m_floatVecType); - m_undefIntVec = UndefValue::get(m_intVecType); - m_extSwizzleVec = 0; - - m_numConsts = 0; -} - -//can only build vectors with all members in the [0, 9] range -llvm::Constant *Storage::shuffleMask(int vec) -{ - if (!m_extSwizzleVec) { - std::vector elems; - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(0.f))); - elems.push_back(ConstantFP::get(Type::FloatTy, APFloat(1.f))); - m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems); - } - - if (m_intVecs.find(vec) != m_intVecs.end()) { - return m_intVecs[vec]; - } - int origVec = vec; - Constant* const_vec = 0; - if (origVec == 0) { - const_vec = Constant::getNullValue(m_intVecType); - } else { - int x = gallivm_x_swizzle(vec); - int y = gallivm_y_swizzle(vec); - int z = gallivm_z_swizzle(vec); - int w = gallivm_w_swizzle(vec); - std::vector elems; - elems.push_back(constantInt(x)); - elems.push_back(constantInt(y)); - elems.push_back(constantInt(z)); - elems.push_back(constantInt(w)); - const_vec = ConstantVector::get(m_intVecType, elems); - } - - m_intVecs[origVec] = const_vec; - return const_vec; -} - -llvm::ConstantInt *Storage::constantInt(int idx) -{ - if (m_constInts.find(idx) != m_constInts.end()) { - return m_constInts[idx]; - } - ConstantInt *const_int = ConstantInt::get(APInt(32, idx)); - m_constInts[idx] = const_int; - return const_int; -} - -llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx) -{ - Value *val = element(InputsArg, idx, indIdx); - LoadInst *load = new LoadInst(val, name("input"), false, m_block); - load->setAlignment(8); - - return load; -} - -llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx) -{ - m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts; - - Value *elem = element(ConstsArg, idx, indIdx); - LoadInst *load = new LoadInst(elem, name("const"), false, m_block); - load->setAlignment(8); - return load; -} - -llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) -{ - Constant *mask = shuffleMask(shuffle); - ShuffleVectorInst *res = - new ShuffleVectorInst(vec, m_extSwizzleVec, mask, - name("shuffle"), m_block); - return res; -} - - -llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx) -{ - Value *elem = element(TempsArg, idx, indIdx); - - LoadInst *load = new LoadInst(elem, name("temp"), false, m_block); - load->setAlignment(8); - - return load; -} - -void Storage::setTempElement(int idx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = 0; - if (m_tempWriteMap[idx]) - templ = tempElement(idx); - val = maskWrite(val, mask, templ); - } - Value *elem = element(TempsArg, idx); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); - m_tempWriteMap[idx] = true; -} - -void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = 0; - if (m_destWriteMap[dstIdx]) - templ = outputElement(dstIdx); - val = maskWrite(val, mask, templ); - } - - Value *elem = element(DestsArg, dstIdx); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); - m_destWriteMap[dstIdx] = true; -} - -llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) -{ - llvm::Value *dst = templ; - if (!dst) - dst = Constant::getNullValue(m_floatVecType); - if ((mask & TGSI_WRITEMASK_X)) { - llvm::Value *x = new ExtractElementInst(src, unsigned(0), - name("x"), m_block); - dst = new InsertElementInst(dst, x, unsigned(0), - name("dstx"), m_block); - } - if ((mask & TGSI_WRITEMASK_Y)) { - llvm::Value *y = new ExtractElementInst(src, unsigned(1), - name("y"), m_block); - dst = new InsertElementInst(dst, y, unsigned(1), - name("dsty"), m_block); - } - if ((mask & TGSI_WRITEMASK_Z)) { - llvm::Value *z = new ExtractElementInst(src, unsigned(2), - name("z"), m_block); - dst = new InsertElementInst(dst, z, unsigned(2), - name("dstz"), m_block); - } - if ((mask & TGSI_WRITEMASK_W)) { - llvm::Value *w = new ExtractElementInst(src, unsigned(3), - name("w"), m_block); - dst = new InsertElementInst(dst, w, unsigned(3), - name("dstw"), m_block); - } - return dst; -} - -const char * Storage::name(const char *prefix) -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -int Storage::numConsts() const -{ - return m_numConsts; -} - -llvm::Value * Storage::addrElement(int idx) const -{ - Value *ret = m_addrs[idx]; - if (!ret) - return m_undefFloatVec; - return ret; -} - -void Storage::setAddrElement(int idx, llvm::Value *val, int mask) -{ - if (mask != TGSI_WRITEMASK_XYZW) { - llvm::Value *templ = m_addrs[idx]; - val = maskWrite(val, mask, templ); - } - m_addrs[idx] = val; -} - -llvm::Value * Storage::extractIndex(llvm::Value *vec) -{ - llvm::Value *x = new ExtractElementInst(vec, unsigned(0), - name("x"), m_block); - return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block); -} - -void Storage::setCurrentBlock(llvm::BasicBlock *block) -{ - m_block = block; -} - -llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx) -{ - Value *elem = element(DestsArg, idx, indIdx); - LoadInst *load = new LoadInst(elem, name("output"), false, m_block); - load->setAlignment(8); - - return load; -} - -llvm::Value * Storage::inputPtr() const -{ - return m_INPUT; -} - -void Storage::pushArguments(llvm::Value *input) -{ - m_argStack.push(m_INPUT); - - m_INPUT = input; -} - -void Storage::popArguments() -{ - m_INPUT = m_argStack.top(); - m_argStack.pop(); -} - -void Storage::pushTemps() -{ - m_extSwizzleVec = 0; -} - -void Storage::popTemps() -{ -} - -llvm::Value * Storage::immediateElement(int idx) -{ - return m_immediates[idx]; -} - -void Storage::addImmediate(float *val) -{ - std::vector vec(4); - vec[0] = ConstantFP::get(Type::FloatTy, APFloat(val[0])); - vec[1] = ConstantFP::get(Type::FloatTy, APFloat(val[1])); - vec[2] = ConstantFP::get(Type::FloatTy, APFloat(val[2])); - vec[3] = ConstantFP::get(Type::FloatTy, APFloat(val[3])); - m_immediates.push_back(ConstantVector::get(m_floatVecType, vec)); -} - - -llvm::Value * Storage::elemPtr(Args arg) -{ - std::vector indices; - indices.push_back(constantInt(0)); - indices.push_back(constantInt(static_cast(arg))); - GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, - indices.begin(), - indices.end(), - name("input_ptr"), - m_block); - return new LoadInst(getElem, name("input_field"), false, m_block); -} - -llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, - llvm::Value *indIdx ) -{ - GetElementPtrInst *getElem = 0; - - if (indIdx) { - getElem = new GetElementPtrInst(ptr, - BinaryOperator::create(Instruction::Add, - indIdx, - constantInt(idx), - name("add"), - m_block), - name("field"), - m_block); - } else { - getElem = new GetElementPtrInst(ptr, - constantInt(idx), - name("field"), - m_block); - } - return getElem; -} - -llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx ) -{ - Value *val = elemPtr(arg); - return elemIdx(val, idx, indIdx); -} - -void Storage::setKilElement(llvm::Value *val) -{ - std::vector indices; - indices.push_back(constantInt(0)); - indices.push_back(constantInt(static_cast(KilArg))); - GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, - indices.begin(), - indices.end(), - name("kil_ptr"), - m_block); - StoreInst *st = new StoreInst(val, elem, false, m_block); - st->setAlignment(8); -} - -#endif //MESA_LLVM - - diff --git a/src/gallium/auxiliary/llvm/storage.h b/src/gallium/auxiliary/llvm/storage.h deleted file mode 100644 index 8574f7554e..0000000000 --- a/src/gallium/auxiliary/llvm/storage.h +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - /* - * Authors: - * Zack Rusin zack@tungstengraphics.com - */ - -#ifndef STORAGE_H -#define STORAGE_H - -#include -#include -#include -#include - -namespace llvm { - class BasicBlock; - class Constant; - class ConstantInt; - class LoadInst; - class Value; - class VectorType; -} - -class Storage -{ -public: - Storage(llvm::BasicBlock *block, - llvm::Value *input); - - llvm::Value *inputPtr() const; - - void setCurrentBlock(llvm::BasicBlock *block); - - llvm::ConstantInt *constantInt(int); - llvm::Constant *shuffleMask(int vec); - llvm::Value *inputElement(int idx, llvm::Value *indIdx =0); - llvm::Value *constElement(int idx, llvm::Value *indIdx =0); - llvm::Value *outputElement(int idx, llvm::Value *indIdx =0); - llvm::Value *tempElement(int idx, llvm::Value *indIdx =0); - llvm::Value *immediateElement(int idx); - - void setOutputElement(int dstIdx, llvm::Value *val, int mask); - void setTempElement(int idx, llvm::Value *val, int mask); - - llvm::Value *addrElement(int idx) const; - void setAddrElement(int idx, llvm::Value *val, int mask); - - void setKilElement(llvm::Value *val); - - llvm::Value *shuffleVector(llvm::Value *vec, int shuffle); - - llvm::Value *extractIndex(llvm::Value *vec); - - int numConsts() const; - - void pushArguments(llvm::Value *input); - void popArguments(); - void pushTemps(); - void popTemps(); - - void addImmediate(float *val); - -private: - llvm::Value *maskWrite(llvm::Value *src, int mask, llvm::Value *templ); - const char *name(const char *prefix); - - enum Args { - DestsArg = 0, - InputsArg = 1, - TempsArg = 2, - ConstsArg = 3, - KilArg = 4 - }; - llvm::Value *elemPtr(Args arg); - llvm::Value *elemIdx(llvm::Value *ptr, int idx, - llvm::Value *indIdx = 0); - llvm::Value *element(Args arg, int idx, llvm::Value *indIdx = 0); - -private: - llvm::BasicBlock *m_block; - llvm::Value *m_INPUT; - - std::map m_constInts; - std::map m_intVecs; - std::vector m_addrs; - std::vector m_immediates; - - llvm::VectorType *m_floatVecType; - llvm::VectorType *m_intVecType; - - char m_name[32]; - int m_idx; - - int m_numConsts; - - std::map m_destWriteMap; - std::map m_tempWriteMap; - - llvm::Value *m_undefFloatVec; - llvm::Value *m_undefIntVec; - llvm::Value *m_extSwizzleVec; - - std::stack m_argStack; - std::stack > m_tempStack; -}; - -#endif diff --git a/src/gallium/auxiliary/llvm/storagesoa.cpp b/src/gallium/auxiliary/llvm/storagesoa.cpp deleted file mode 100644 index ed0674a96f..0000000000 --- a/src/gallium/auxiliary/llvm/storagesoa.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "storagesoa.h" - -#include "gallivm_p.h" - -#include "pipe/p_shader_tokens.h" -#include "pipe/p_debug.h" - -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace llvm; - - -StorageSoa::StorageSoa(llvm::BasicBlock *block, - llvm::Value *input, - llvm::Value *output, - llvm::Value *consts, - llvm::Value *temps) - : m_block(block), - m_input(input), - m_output(output), - m_consts(consts), - m_temps(temps), - m_immediates(0), - m_idx(0) -{ -} - -void StorageSoa::addImmediate(float *vec) -{ - std::vector vals(4); - vals[0] = vec[0]; - vals[1] = vec[1]; - vals[2] = vec[2]; - vals[3] = vec[3]; - m_immediatesToFlush.push_back(vals); -} - -void StorageSoa::declareImmediates() -{ - if (m_immediatesToFlush.empty()) - return; - - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorChannels = ArrayType::get(vectorType, 4); - ArrayType *arrayType = ArrayType::get(vectorChannels, m_immediatesToFlush.size()); - - m_immediates = new GlobalVariable( - /*Type=*/arrayType, - /*isConstant=*/false, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name("immediates"), - currentModule()); - - std::vector arrayVals; - for (unsigned int i = 0; i < m_immediatesToFlush.size(); ++i) { - std::vector vec = m_immediatesToFlush[i]; - std::vector vals(4); - std::vector channelArray; - - vals[0] = vec[0]; vals[1] = vec[0]; vals[2] = vec[0]; vals[3] = vec[0]; - llvm::Constant *xChannel = createConstGlobalVector(vals); - - vals[0] = vec[1]; vals[1] = vec[1]; vals[2] = vec[1]; vals[3] = vec[1]; - llvm::Constant *yChannel = createConstGlobalVector(vals); - - vals[0] = vec[2]; vals[1] = vec[2]; vals[2] = vec[2]; vals[3] = vec[2]; - llvm::Constant *zChannel = createConstGlobalVector(vals); - - vals[0] = vec[3]; vals[1] = vec[3]; vals[2] = vec[3]; vals[3] = vec[3]; - llvm::Constant *wChannel = createConstGlobalVector(vals); - channelArray.push_back(xChannel); - channelArray.push_back(yChannel); - channelArray.push_back(zChannel); - channelArray.push_back(wChannel); - Constant *constChannels = ConstantArray::get(vectorChannels, - channelArray); - arrayVals.push_back(constChannels); - } - Constant *constArray = ConstantArray::get(arrayType, arrayVals); - m_immediates->setInitializer(constArray); - - m_immediatesToFlush.clear(); -} - -llvm::Value *StorageSoa::addrElement(int idx) const -{ - std::map::const_iterator itr = m_addresses.find(idx); - if (itr == m_addresses.end()) { - debug_printf("Trying to access invalid shader 'address'\n"); - return 0; - } - llvm::Value * res = (*itr).second; - - res = new LoadInst(res, name("addr"), false, m_block); - - return res; -} - -std::vector StorageSoa::inputElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_input, idx, 0); - res[1] = element(m_input, idx, 1); - res[2] = element(m_input, idx, 2); - res[3] = element(m_input, idx, 3); - - return res; -} - -std::vector StorageSoa::constElement(llvm::Value *idx) -{ - std::vector res(4); - llvm::Value *xChannel, *yChannel, *zChannel, *wChannel; - - xChannel = elementPointer(m_consts, idx, 0); - yChannel = elementPointer(m_consts, idx, 1); - zChannel = elementPointer(m_consts, idx, 2); - wChannel = elementPointer(m_consts, idx, 3); - - res[0] = alignedArrayLoad(xChannel); - res[1] = alignedArrayLoad(yChannel); - res[2] = alignedArrayLoad(zChannel); - res[3] = alignedArrayLoad(wChannel); - - return res; -} - -std::vector StorageSoa::outputElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_output, idx, 0); - res[1] = element(m_output, idx, 1); - res[2] = element(m_output, idx, 2); - res[3] = element(m_output, idx, 3); - - return res; -} - -std::vector StorageSoa::tempElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_temps, idx, 0); - res[1] = element(m_temps, idx, 1); - res[2] = element(m_temps, idx, 2); - res[3] = element(m_temps, idx, 3); - - return res; -} - -std::vector StorageSoa::immediateElement(llvm::Value *idx) -{ - std::vector res(4); - - res[0] = element(m_immediates, idx, 0); - res[1] = element(m_immediates, idx, 1); - res[2] = element(m_immediates, idx, 2); - res[3] = element(m_immediates, idx, 3); - - return res; -} - -llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, - int channel) const -{ - std::vector indices; - if (m_immediates == ptr) - indices.push_back(constantInt(0)); - indices.push_back(index); - indices.push_back(constantInt(channel)); - - GetElementPtrInst *getElem = new GetElementPtrInst(ptr, - indices.begin(), - indices.end(), - name("ptr"), - m_block); - return getElem; -} - -llvm::Value * StorageSoa::element(llvm::Value *ptr, llvm::Value *index, - int channel) const -{ - llvm::Value *res = elementPointer(ptr, index, channel); - LoadInst *load = new LoadInst(res, name("element"), false, m_block); - //load->setAlignment(8); - return load; -} - -const char * StorageSoa::name(const char *prefix) const -{ - ++m_idx; - snprintf(m_name, 32, "%s%d", prefix, m_idx); - return m_name; -} - -llvm::ConstantInt * StorageSoa::constantInt(int idx) const -{ - if (m_constInts.find(idx) != m_constInts.end()) { - return m_constInts[idx]; - } - ConstantInt *constInt = ConstantInt::get(APInt(32, idx)); - m_constInts[idx] = constInt; - return constInt; -} - -llvm::Value *StorageSoa::alignedArrayLoad(llvm::Value *val) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - PointerType *vectorPtr = PointerType::get(vectorType, 0); - - CastInst *cast = new BitCastInst(val, vectorPtr, name("toVector"), m_block); - LoadInst *load = new LoadInst(cast, name("alignLoad"), false, m_block); - load->setAlignment(8); - return load; -} - -llvm::Module * StorageSoa::currentModule() const -{ - if (!m_block || !m_block->getParent()) - return 0; - - return m_block->getParent()->getParent(); -} - -llvm::Constant * StorageSoa::createConstGlobalVector(const std::vector &vec) -{ - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - std::vector immValues; - ConstantFP *constx = ConstantFP::get(Type::FloatTy, APFloat(vec[0])); - ConstantFP *consty = ConstantFP::get(Type::FloatTy, APFloat(vec[1])); - ConstantFP *constz = ConstantFP::get(Type::FloatTy, APFloat(vec[2])); - ConstantFP *constw = ConstantFP::get(Type::FloatTy, APFloat(vec[3])); - immValues.push_back(constx); - immValues.push_back(consty); - immValues.push_back(constz); - immValues.push_back(constw); - Constant *constVector = ConstantVector::get(vectorType, immValues); - - return constVector; -} - -std::vector StorageSoa::load(Argument type, int idx, int swizzle, - llvm::Value *indIdx) -{ - std::vector val(4); - - //if we have an indirect index, always use that - // if not use the integer offset to create one - llvm::Value *realIndex = 0; - if (indIdx) - realIndex = indIdx; - else - realIndex = constantInt(idx); - debug_printf("XXXXXXXXX realIdx = %p, indIdx = %p\n", realIndex, indIdx); - - switch(type) { - case Input: - val = inputElement(realIndex); - break; - case Output: - val = outputElement(realIndex); - break; - case Temp: - val = tempElement(realIndex); - break; - case Const: - val = constElement(realIndex); - break; - case Immediate: - val = immediateElement(realIndex); - break; - case Address: - debug_printf("Address not handled in the load phase!\n"); - assert(0); - break; - } - if (!gallivm_is_swizzle(swizzle)) - return val; - - std::vector res(4); - - res[0] = val[gallivm_x_swizzle(swizzle)]; - res[1] = val[gallivm_y_swizzle(swizzle)]; - res[2] = val[gallivm_z_swizzle(swizzle)]; - res[3] = val[gallivm_w_swizzle(swizzle)]; - return res; -} - -void StorageSoa::store(Argument type, int idx, const std::vector &val, - int mask) -{ - llvm::Value *out = 0; - switch(type) { - case Output: - out = m_output; - break; - case Temp: - out = m_temps; - break; - case Input: - out = m_input; - break; - case Address: { - llvm::Value *addr = m_addresses[idx]; - if (!addr) { - addAddress(idx); - addr = m_addresses[idx]; - assert(addr); - } - new StoreInst(val[0], addr, false, m_block); - return; - break; - } - default: - debug_printf("Can't save output of this type: %d !\n", type); - assert(0); - break; - } - llvm::Value *realIndex = constantInt(idx); - if ((mask & TGSI_WRITEMASK_X)) { - llvm::Value *xChannel = elementPointer(out, realIndex, 0); - new StoreInst(val[0], xChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_Y)) { - llvm::Value *yChannel = elementPointer(out, realIndex, 1); - new StoreInst(val[1], yChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_Z)) { - llvm::Value *zChannel = elementPointer(out, realIndex, 2); - new StoreInst(val[2], zChannel, false, m_block); - } - if ((mask & TGSI_WRITEMASK_W)) { - llvm::Value *wChannel = elementPointer(out, realIndex, 3); - new StoreInst(val[3], wChannel, false, m_block); - } -} - -void StorageSoa::addAddress(int idx) -{ - GlobalVariable *val = new GlobalVariable( - /*Type=*/IntegerType::get(32), - /*isConstant=*/false, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Initializer=*/0, // has initializer, specified below - /*Name=*/name("address"), - currentModule()); - val->setInitializer(Constant::getNullValue(IntegerType::get(32))); - - debug_printf("adding to %d\n", idx); - m_addresses[idx] = val; -} diff --git a/src/gallium/auxiliary/llvm/storagesoa.h b/src/gallium/auxiliary/llvm/storagesoa.h deleted file mode 100644 index 6443351f27..0000000000 --- a/src/gallium/auxiliary/llvm/storagesoa.h +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef STORAGESOA_H -#define STORAGESOA_H - -#include -#include -#include - -namespace llvm { - class BasicBlock; - class Constant; - class ConstantInt; - class GlobalVariable; - class LoadInst; - class Value; - class VectorType; - class Module; -} - -class StorageSoa -{ -public: - enum Argument { - Input, - Output, - Temp, - Const, - Immediate, - Address - }; -public: - StorageSoa(llvm::BasicBlock *block, - llvm::Value *input, - llvm::Value *output, - llvm::Value *consts, - llvm::Value *temps); - - - std::vector load(Argument type, int idx, int swizzle, - llvm::Value *indIdx =0); - void store(Argument type, int idx, const std::vector &val, - int mask); - - void addImmediate(float *vec); - void declareImmediates(); - - void addAddress(int idx); - - llvm::Value * addrElement(int idx) const; - - llvm::ConstantInt *constantInt(int) const; -private: - llvm::Value *elementPointer(llvm::Value *ptr, llvm::Value *indIdx, - int channel) const; - llvm::Value *element(llvm::Value *ptr, llvm::Value *idx, - int channel) const; - const char *name(const char *prefix) const; - llvm::Value *alignedArrayLoad(llvm::Value *val); - llvm::Module *currentModule() const; - llvm::Constant *createConstGlobalVector(const std::vector &vec); - - std::vector inputElement(llvm::Value *indIdx); - std::vector constElement(llvm::Value *indIdx); - std::vector outputElement(llvm::Value *indIdx); - std::vector tempElement(llvm::Value *indIdx); - std::vector immediateElement(llvm::Value *indIdx); -private: - llvm::BasicBlock *m_block; - - llvm::Value *m_input; - llvm::Value *m_output; - llvm::Value *m_consts; - llvm::Value *m_temps; - llvm::GlobalVariable *m_immediates; - - std::map m_addresses; - - std::vector > m_immediatesToFlush; - - mutable std::map m_constInts; - mutable char m_name[32]; - mutable int m_idx; -}; - -#endif diff --git a/src/gallium/auxiliary/llvm/tgsitollvm.cpp b/src/gallium/auxiliary/llvm/tgsitollvm.cpp deleted file mode 100644 index 2cb4acce32..0000000000 --- a/src/gallium/auxiliary/llvm/tgsitollvm.cpp +++ /dev/null @@ -1,1221 +0,0 @@ -#include "tgsitollvm.h" - -#include "gallivm.h" -#include "gallivm_p.h" - -#include "storage.h" -#include "instructions.h" -#include "storagesoa.h" -#include "instructionssoa.h" - -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_parse.h" -#include "tgsi/exec/tgsi_exec.h" -#include "tgsi/util/tgsi_util.h" -#include "tgsi/util/tgsi_build.h" -#include "tgsi/util/tgsi_dump.h" - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include - -using namespace llvm; - -static inline FunctionType *vertexShaderFunctionType() -{ - //Function takes three arguments, - // the calling code has to make sure the types it will - // pass are castable to the following: - // [4 x <4 x float>] inputs, - // [4 x <4 x float>] output, - // [4 x [4 x float]] consts, - // [4 x <4 x float>] temps - - std::vector funcArgs; - VectorType *vectorType = VectorType::get(Type::FloatTy, 4); - ArrayType *vectorArray = ArrayType::get(vectorType, 4); - PointerType *vectorArrayPtr = PointerType::get(vectorArray, 0); - - ArrayType *floatArray = ArrayType::get(Type::FloatTy, 4); - ArrayType *constsArray = ArrayType::get(floatArray, 4); - PointerType *constsArrayPtr = PointerType::get(constsArray, 0); - - funcArgs.push_back(vectorArrayPtr);//inputs - funcArgs.push_back(vectorArrayPtr);//output - funcArgs.push_back(constsArrayPtr);//consts - funcArgs.push_back(vectorArrayPtr);//temps - - FunctionType *functionType = FunctionType::get( - /*Result=*/Type::VoidTy, - /*Params=*/funcArgs, - /*isVarArg=*/false); - - return functionType; -} - -static inline void -add_interpolator(struct gallivm_ir *ir, - struct gallivm_interpolate *interp) -{ - ir->interpolators[ir->num_interp] = *interp; - ++ir->num_interp; -} - -static void -translate_declaration(struct gallivm_ir *prog, - llvm::Module *module, - Storage *storage, - struct tgsi_full_declaration *decl, - struct tgsi_full_declaration *fd) -{ - if (decl->Declaration.File == TGSI_FILE_INPUT) { - unsigned first, last, mask; - uint interp_method; - - assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE); - - first = decl->u.DeclarationRange.First; - last = decl->u.DeclarationRange.Last; - mask = decl->Declaration.UsageMask; - - /* Do not touch WPOS.xy */ - if (first == 0) { - mask &= ~TGSI_WRITEMASK_XY; - if (mask == TGSI_WRITEMASK_NONE) { - first++; - if (first > last) { - return; - } - } - } - - interp_method = decl->Interpolation.Interpolate; - - if (mask == TGSI_WRITEMASK_XYZW) { - unsigned i, j; - - for (i = first; i <= last; i++) { - for (j = 0; j < NUM_CHANNELS; j++) { - //interp( mach, i, j ); - struct gallivm_interpolate interp; - interp.type = interp_method; - interp.attrib = i; - interp.chan = j; - add_interpolator(prog, &interp); - } - } - } else { - unsigned i, j; - for( j = 0; j < NUM_CHANNELS; j++ ) { - if( mask & (1 << j) ) { - for( i = first; i <= last; i++ ) { - struct gallivm_interpolate interp; - interp.type = interp_method; - interp.attrib = i; - interp.chan = j; - add_interpolator(prog, &interp); - } - } - } - } - } -} - -static void -translate_declarationir(struct gallivm_ir *, - llvm::Module *, - StorageSoa *storage, - struct tgsi_full_declaration *decl, - struct tgsi_full_declaration *) -{ - if (decl->Declaration.File == TGSI_FILE_ADDRESS) { - int idx = decl->u.DeclarationRange.First; - storage->addAddress(idx); - } -} - -static void -translate_immediate(Storage *storage, - struct tgsi_full_immediate *imm) -{ - float vec[4]; - int i; - for (i = 0; i < imm->Immediate.Size - 1; ++i) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - vec[i] = imm->u.ImmediateFloat32[i].Float; - break; - default: - assert(0); - } - } - storage->addImmediate(vec); -} - - -static void -translate_immediateir(StorageSoa *storage, - struct tgsi_full_immediate *imm) -{ - float vec[4]; - int i; - for (i = 0; i < imm->Immediate.Size - 1; ++i) { - switch (imm->Immediate.DataType) { - case TGSI_IMM_FLOAT32: - vec[i] = imm->u.ImmediateFloat32[i].Float; - break; - default: - assert(0); - } - } - storage->addImmediate(vec); -} - -static inline int -swizzleInt(struct tgsi_full_src_register *src) -{ - int swizzle = 0; - int start = 1000; - - for (int k = 0; k < 4; ++k) { - swizzle += tgsi_util_get_full_src_register_extswizzle(src, k) * start; - start /= 10; - } - return swizzle; -} - -static inline llvm::Value * -swizzleVector(llvm::Value *val, struct tgsi_full_src_register *src, - Storage *storage) -{ - int swizzle = swizzleInt(src); - - if (gallivm_is_swizzle(swizzle)) { - /*fprintf(stderr, "XXXXXXXX swizzle = %d\n", swizzle);*/ - val = storage->shuffleVector(val, swizzle); - } - return val; -} - -static void -translate_instruction(llvm::Module *module, - Storage *storage, - Instructions *instr, - struct tgsi_full_instruction *inst, - struct tgsi_full_instruction *fi, - unsigned instno) -{ - llvm::Value *inputs[4]; - inputs[0] = 0; - inputs[1] = 0; - inputs[2] = 0; - inputs[3] = 0; - - for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - llvm::Value *val = 0; - llvm::Value *indIdx = 0; - - if (src->SrcRegister.Indirect) { - indIdx = storage->addrElement(src->SrcRegisterInd.Index); - indIdx = storage->extractIndex(indIdx); - } - if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { - val = storage->constElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { - val = storage->inputElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { - val = storage->tempElement(src->SrcRegister.Index); - } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { - val = storage->outputElement(src->SrcRegister.Index, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { - val = storage->immediateElement(src->SrcRegister.Index); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); - return; - } - - inputs[i] = swizzleVector(val, src, storage); - } - - /*if (inputs[0]) - instr->printVector(inputs[0]); - if (inputs[1]) - instr->printVector(inputs[1]);*/ - llvm::Value *out = 0; - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: { - out = instr->arl(inputs[0]); - } - break; - case TGSI_OPCODE_MOV: { - out = inputs[0]; - } - break; - case TGSI_OPCODE_LIT: { - out = instr->lit(inputs[0]); - } - break; - case TGSI_OPCODE_RCP: { - out = instr->rcp(inputs[0]); - } - break; - case TGSI_OPCODE_RSQ: { - out = instr->rsq(inputs[0]); - } - break; - case TGSI_OPCODE_EXP: - break; - case TGSI_OPCODE_LOG: - break; - case TGSI_OPCODE_MUL: { - out = instr->mul(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ADD: { - out = instr->add(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP3: { - out = instr->dp3(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP4: { - out = instr->dp4(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DST: { - out = instr->dst(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MIN: { - out = instr->min(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAX: { - out = instr->max(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SLT: { - out = instr->slt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SGE: { - out = instr->sge(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MAD: { - out = instr->madd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SUB: { - out = instr->sub(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_LERP: { - out = instr->lerp(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_CND: - break; - case TGSI_OPCODE_CND0: - break; - case TGSI_OPCODE_DOT2ADD: - break; - case TGSI_OPCODE_INDEX: - break; - case TGSI_OPCODE_NEGATE: - break; - case TGSI_OPCODE_FRAC: { - out = instr->frc(inputs[0]); - } - break; - case TGSI_OPCODE_CLAMP: - break; - case TGSI_OPCODE_FLOOR: { - out = instr->floor(inputs[0]); - } - break; - case TGSI_OPCODE_ROUND: - break; - case TGSI_OPCODE_EXPBASE2: { - out = instr->ex2(inputs[0]); - } - break; - case TGSI_OPCODE_LOGBASE2: { - out = instr->lg2(inputs[0]); - } - break; - case TGSI_OPCODE_POWER: { - out = instr->pow(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_CROSSPRODUCT: { - out = instr->cross(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_MULTIPLYMATRIX: - break; - case TGSI_OPCODE_ABS: { - out = instr->abs(inputs[0]); - } - break; - case TGSI_OPCODE_RCC: - break; - case TGSI_OPCODE_DPH: { - out = instr->dph(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_COS: { - out = instr->cos(inputs[0]); - } - break; - case TGSI_OPCODE_DDX: - break; - case TGSI_OPCODE_DDY: - break; - case TGSI_OPCODE_KILP: { - out = instr->kilp(inputs[0]); - storage->setKilElement(out); - return; - } - break; - case TGSI_OPCODE_PK2H: - break; - case TGSI_OPCODE_PK2US: - break; - case TGSI_OPCODE_PK4B: - break; - case TGSI_OPCODE_PK4UB: - break; - case TGSI_OPCODE_RFL: - break; - case TGSI_OPCODE_SEQ: - break; - case TGSI_OPCODE_SFL: - break; - case TGSI_OPCODE_SGT: { - out = instr->sgt(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_SIN: { - out = instr->sin(inputs[0]); - } - break; - case TGSI_OPCODE_SLE: - break; - case TGSI_OPCODE_SNE: - break; - case TGSI_OPCODE_STR: - break; - case TGSI_OPCODE_TEX: - break; - case TGSI_OPCODE_TXD: - break; - case TGSI_OPCODE_UP2H: - break; - case TGSI_OPCODE_UP2US: - break; - case TGSI_OPCODE_UP4B: - break; - case TGSI_OPCODE_UP4UB: - break; - case TGSI_OPCODE_X2D: - break; - case TGSI_OPCODE_ARA: - break; - case TGSI_OPCODE_ARR: - break; - case TGSI_OPCODE_BRA: - break; - case TGSI_OPCODE_CAL: { - instr->cal(inst->InstructionExtLabel.Label, storage->inputPtr()); - return; - } - break; - case TGSI_OPCODE_RET: { - instr->end(); - return; - } - break; - case TGSI_OPCODE_SSG: - break; - case TGSI_OPCODE_CMP: { - out = instr->cmp(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SCS: { - out = instr->scs(inputs[0]); - } - break; - case TGSI_OPCODE_TXB: - break; - case TGSI_OPCODE_NRM: - break; - case TGSI_OPCODE_DIV: - break; - case TGSI_OPCODE_DP2: - break; - case TGSI_OPCODE_TXL: - break; - case TGSI_OPCODE_BRK: { - instr->brk(); - return; - } - break; - case TGSI_OPCODE_IF: { - instr->ifop(inputs[0]); - storage->setCurrentBlock(instr->currentBlock()); - return; //just update the state - } - break; - case TGSI_OPCODE_LOOP: - break; - case TGSI_OPCODE_REP: - break; - case TGSI_OPCODE_ELSE: { - instr->elseop(); - storage->setCurrentBlock(instr->currentBlock()); - return; //only state update - } - break; - case TGSI_OPCODE_ENDIF: { - instr->endif(); - storage->setCurrentBlock(instr->currentBlock()); - return; //just update the state - } - break; - case TGSI_OPCODE_ENDLOOP: - break; - case TGSI_OPCODE_ENDREP: - break; - case TGSI_OPCODE_PUSHA: - break; - case TGSI_OPCODE_POPA: - break; - case TGSI_OPCODE_CEIL: - break; - case TGSI_OPCODE_I2F: - break; - case TGSI_OPCODE_NOT: - break; - case TGSI_OPCODE_TRUNC: { - out = instr->trunc(inputs[0]); - } - break; - case TGSI_OPCODE_SHL: - break; - case TGSI_OPCODE_SHR: - break; - case TGSI_OPCODE_AND: - break; - case TGSI_OPCODE_OR: - break; - case TGSI_OPCODE_MOD: - break; - case TGSI_OPCODE_XOR: - break; - case TGSI_OPCODE_SAD: - break; - case TGSI_OPCODE_TXF: - break; - case TGSI_OPCODE_TXQ: - break; - case TGSI_OPCODE_CONT: - break; - case TGSI_OPCODE_EMIT: - break; - case TGSI_OPCODE_ENDPRIM: - break; - case TGSI_OPCODE_BGNLOOP2: { - instr->beginLoop(); - storage->setCurrentBlock(instr->currentBlock()); - return; - } - break; - case TGSI_OPCODE_BGNSUB: { - instr->bgnSub(instno); - storage->setCurrentBlock(instr->currentBlock()); - storage->pushTemps(); - return; - } - break; - case TGSI_OPCODE_ENDLOOP2: { - instr->endLoop(); - storage->setCurrentBlock(instr->currentBlock()); - return; - } - break; - case TGSI_OPCODE_ENDSUB: { - instr->endSub(); - storage->setCurrentBlock(instr->currentBlock()); - storage->popArguments(); - storage->popTemps(); - return; - } - break; - case TGSI_OPCODE_NOISE1: - break; - case TGSI_OPCODE_NOISE2: - break; - case TGSI_OPCODE_NOISE3: - break; - case TGSI_OPCODE_NOISE4: - break; - case TGSI_OPCODE_NOP: - break; - case TGSI_OPCODE_TEXBEM: - break; - case TGSI_OPCODE_TEXBEML: - break; - case TGSI_OPCODE_TEXREG2AR: - break; - case TGSI_OPCODE_TEXM3X2PAD: - break; - case TGSI_OPCODE_TEXM3X2TEX: - break; - case TGSI_OPCODE_TEXM3X3PAD: - break; - case TGSI_OPCODE_TEXM3X3TEX: - break; - case TGSI_OPCODE_TEXM3X3SPEC: - break; - case TGSI_OPCODE_TEXM3X3VSPEC: - break; - case TGSI_OPCODE_TEXREG2GB: - break; - case TGSI_OPCODE_TEXREG2RGB: - break; - case TGSI_OPCODE_TEXDP3TEX: - break; - case TGSI_OPCODE_TEXDP3: - break; - case TGSI_OPCODE_TEXM3X3: - break; - case TGSI_OPCODE_TEXM3X2DEPTH: - break; - case TGSI_OPCODE_TEXDEPTH: - break; - case TGSI_OPCODE_BEM: - break; - case TGSI_OPCODE_M4X3: - break; - case TGSI_OPCODE_M3X4: - break; - case TGSI_OPCODE_M3X3: - break; - case TGSI_OPCODE_M3X2: - break; - case TGSI_OPCODE_NRM4: - break; - case TGSI_OPCODE_CALLNZ: - break; - case TGSI_OPCODE_IFC: - break; - case TGSI_OPCODE_BREAKC: - break; - case TGSI_OPCODE_KIL: - break; - case TGSI_OPCODE_END: - instr->end(); - return; - break; - default: - fprintf(stderr, "ERROR: Unknown opcode %d\n", - inst->Instruction.Opcode); - assert(0); - break; - } - - if (!out) { - fprintf(stderr, "ERROR: unsupported opcode %d\n", - inst->Instruction.Opcode); - assert(!"Unsupported opcode"); - } - - /* # not sure if we need this */ - switch( inst->Instruction.Saturate ) { - case TGSI_SAT_NONE: - break; - case TGSI_SAT_ZERO_ONE: - /*TXT( "_SAT" );*/ - break; - case TGSI_SAT_MINUS_PLUS_ONE: - /*TXT( "_SAT[-1,1]" );*/ - break; - default: - assert( 0 ); - } - - /* store results */ - for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - storage->setOutputElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { - storage->setTempElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { - storage->setAddrElement(dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } - } -} - - -static void -translate_instructionir(llvm::Module *module, - StorageSoa *storage, - InstructionsSoa *instr, - struct tgsi_full_instruction *inst, - struct tgsi_full_instruction *fi, - unsigned instno) -{ - std::vector< std::vector > inputs(inst->Instruction.NumSrcRegs); - - for (int i = 0; i < inst->Instruction.NumSrcRegs; ++i) { - struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; - std::vector val; - llvm::Value *indIdx = 0; - int swizzle = swizzleInt(src); - - if (src->SrcRegister.Indirect) { - indIdx = storage->addrElement(src->SrcRegisterInd.Index); - } - if (src->SrcRegister.File == TGSI_FILE_CONSTANT) { - val = storage->load(StorageSoa::Const, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_INPUT) { - val = storage->load(StorageSoa::Input, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_TEMPORARY) { - val = storage->load(StorageSoa::Temp, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_OUTPUT) { - val = storage->load(StorageSoa::Output, - src->SrcRegister.Index, swizzle, indIdx); - } else if (src->SrcRegister.File == TGSI_FILE_IMMEDIATE) { - val = storage->load(StorageSoa::Immediate, - src->SrcRegister.Index, swizzle, indIdx); - } else { - fprintf(stderr, "ERROR: not supported llvm source %d\n", src->SrcRegister.File); - return; - } - - inputs[i] = val; - } - - std::vector out(4); - switch (inst->Instruction.Opcode) { - case TGSI_OPCODE_ARL: { - out = instr->arl(inputs[0]); - } - break; - case TGSI_OPCODE_MOV: { - out = inputs[0]; - } - break; - case TGSI_OPCODE_LIT: { - } - break; - case TGSI_OPCODE_RCP: { - } - break; - case TGSI_OPCODE_RSQ: { - } - break; - case TGSI_OPCODE_EXP: - break; - case TGSI_OPCODE_LOG: - break; - case TGSI_OPCODE_MUL: { - out = instr->mul(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_ADD: { - out = instr->add(inputs[0], inputs[1]); - } - break; - case TGSI_OPCODE_DP3: { - } - break; - case TGSI_OPCODE_DP4: { - } - break; - case TGSI_OPCODE_DST: { - } - break; - case TGSI_OPCODE_MIN: { - } - break; - case TGSI_OPCODE_MAX: { - } - break; - case TGSI_OPCODE_SLT: { - } - break; - case TGSI_OPCODE_SGE: { - } - break; - case TGSI_OPCODE_MAD: { - out = instr->madd(inputs[0], inputs[1], inputs[2]); - } - break; - case TGSI_OPCODE_SUB: { - } - break; - case TGSI_OPCODE_LERP: { - } - break; - case TGSI_OPCODE_CND: - break; - case TGSI_OPCODE_CND0: - break; - case TGSI_OPCODE_DOT2ADD: - break; - case TGSI_OPCODE_INDEX: - break; - case TGSI_OPCODE_NEGATE: - break; - case TGSI_OPCODE_FRAC: { - } - break; - case TGSI_OPCODE_CLAMP: - break; - case TGSI_OPCODE_FLOOR: { - } - break; - case TGSI_OPCODE_ROUND: - break; - case TGSI_OPCODE_EXPBASE2: { - } - break; - case TGSI_OPCODE_LOGBASE2: { - } - break; - case TGSI_OPCODE_POWER: { - } - break; - case TGSI_OPCODE_CROSSPRODUCT: { - } - break; - case TGSI_OPCODE_MULTIPLYMATRIX: - break; - case TGSI_OPCODE_ABS: { - } - break; - case TGSI_OPCODE_RCC: - break; - case TGSI_OPCODE_DPH: { - } - break; - case TGSI_OPCODE_COS: { - } - break; - case TGSI_OPCODE_DDX: - break; - case TGSI_OPCODE_DDY: - break; - case TGSI_OPCODE_KILP: { - } - break; - case TGSI_OPCODE_PK2H: - break; - case TGSI_OPCODE_PK2US: - break; - case TGSI_OPCODE_PK4B: - break; - case TGSI_OPCODE_PK4UB: - break; - case TGSI_OPCODE_RFL: - break; - case TGSI_OPCODE_SEQ: - break; - case TGSI_OPCODE_SFL: - break; - case TGSI_OPCODE_SGT: { - } - break; - case TGSI_OPCODE_SIN: { - } - break; - case TGSI_OPCODE_SLE: - break; - case TGSI_OPCODE_SNE: - break; - case TGSI_OPCODE_STR: - break; - case TGSI_OPCODE_TEX: - break; - case TGSI_OPCODE_TXD: - break; - case TGSI_OPCODE_UP2H: - break; - case TGSI_OPCODE_UP2US: - break; - case TGSI_OPCODE_UP4B: - break; - case TGSI_OPCODE_UP4UB: - break; - case TGSI_OPCODE_X2D: - break; - case TGSI_OPCODE_ARA: - break; - case TGSI_OPCODE_ARR: - break; - case TGSI_OPCODE_BRA: - break; - case TGSI_OPCODE_CAL: { - } - break; - case TGSI_OPCODE_RET: { - } - break; - case TGSI_OPCODE_SSG: - break; - case TGSI_OPCODE_CMP: { - } - break; - case TGSI_OPCODE_SCS: { - } - break; - case TGSI_OPCODE_TXB: - break; - case TGSI_OPCODE_NRM: - break; - case TGSI_OPCODE_DIV: - break; - case TGSI_OPCODE_DP2: - break; - case TGSI_OPCODE_TXL: - break; - case TGSI_OPCODE_BRK: { - } - break; - case TGSI_OPCODE_IF: { - } - break; - case TGSI_OPCODE_LOOP: - break; - case TGSI_OPCODE_REP: - break; - case TGSI_OPCODE_ELSE: { - } - break; - case TGSI_OPCODE_ENDIF: { - } - break; - case TGSI_OPCODE_ENDLOOP: - break; - case TGSI_OPCODE_ENDREP: - break; - case TGSI_OPCODE_PUSHA: - break; - case TGSI_OPCODE_POPA: - break; - case TGSI_OPCODE_CEIL: - break; - case TGSI_OPCODE_I2F: - break; - case TGSI_OPCODE_NOT: - break; - case TGSI_OPCODE_TRUNC: { - } - break; - case TGSI_OPCODE_SHL: - break; - case TGSI_OPCODE_SHR: - break; - case TGSI_OPCODE_AND: - break; - case TGSI_OPCODE_OR: - break; - case TGSI_OPCODE_MOD: - break; - case TGSI_OPCODE_XOR: - break; - case TGSI_OPCODE_SAD: - break; - case TGSI_OPCODE_TXF: - break; - case TGSI_OPCODE_TXQ: - break; - case TGSI_OPCODE_CONT: - break; - case TGSI_OPCODE_EMIT: - break; - case TGSI_OPCODE_ENDPRIM: - break; - case TGSI_OPCODE_BGNLOOP2: { - } - break; - case TGSI_OPCODE_BGNSUB: { - } - break; - case TGSI_OPCODE_ENDLOOP2: { - } - break; - case TGSI_OPCODE_ENDSUB: { - } - break; - case TGSI_OPCODE_NOISE1: - break; - case TGSI_OPCODE_NOISE2: - break; - case TGSI_OPCODE_NOISE3: - break; - case TGSI_OPCODE_NOISE4: - break; - case TGSI_OPCODE_NOP: - break; - case TGSI_OPCODE_TEXBEM: - break; - case TGSI_OPCODE_TEXBEML: - break; - case TGSI_OPCODE_TEXREG2AR: - break; - case TGSI_OPCODE_TEXM3X2PAD: - break; - case TGSI_OPCODE_TEXM3X2TEX: - break; - case TGSI_OPCODE_TEXM3X3PAD: - break; - case TGSI_OPCODE_TEXM3X3TEX: - break; - case TGSI_OPCODE_TEXM3X3SPEC: - break; - case TGSI_OPCODE_TEXM3X3VSPEC: - break; - case TGSI_OPCODE_TEXREG2GB: - break; - case TGSI_OPCODE_TEXREG2RGB: - break; - case TGSI_OPCODE_TEXDP3TEX: - break; - case TGSI_OPCODE_TEXDP3: - break; - case TGSI_OPCODE_TEXM3X3: - break; - case TGSI_OPCODE_TEXM3X2DEPTH: - break; - case TGSI_OPCODE_TEXDEPTH: - break; - case TGSI_OPCODE_BEM: - break; - case TGSI_OPCODE_M4X3: - break; - case TGSI_OPCODE_M3X4: - break; - case TGSI_OPCODE_M3X3: - break; - case TGSI_OPCODE_M3X2: - break; - case TGSI_OPCODE_NRM4: - break; - case TGSI_OPCODE_CALLNZ: - break; - case TGSI_OPCODE_IFC: - break; - case TGSI_OPCODE_BREAKC: - break; - case TGSI_OPCODE_KIL: - break; - case TGSI_OPCODE_END: - instr->end(); - return; - break; - default: - fprintf(stderr, "ERROR: Unknown opcode %d\n", - inst->Instruction.Opcode); - assert(0); - break; - } - - if (!out[0]) { - fprintf(stderr, "ERROR: unsupported opcode %d\n", - inst->Instruction.Opcode); - assert(!"Unsupported opcode"); - } - - /* store results */ - for (int i = 0; i < inst->Instruction.NumDstRegs; ++i) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - - if (dst->DstRegister.File == TGSI_FILE_OUTPUT) { - storage->store(StorageSoa::Output, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_TEMPORARY) { - storage->store(StorageSoa::Temp, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else if (dst->DstRegister.File == TGSI_FILE_ADDRESS) { - storage->store(StorageSoa::Address, - dst->DstRegister.Index, out, dst->DstRegister.WriteMask); - } else { - fprintf(stderr, "ERROR: unsupported LLVM destination!"); - assert(!"wrong destination"); - } - } -} - -llvm::Module * -tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) -{ - llvm::Module *mod = new Module("shader"); - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; - Function* shader = mod->getFunction("execute_shader"); - std::ostringstream stream; - if (ir->type == GALLIVM_VS) { - stream << "vs_shader"; - } else { - stream << "fs_shader"; - } - stream << ir->id; - std::string func_name = stream.str(); - shader->setName(func_name.c_str()); - - Function::arg_iterator args = shader->arg_begin(); - Value *ptr_INPUT = args++; - ptr_INPUT->setName("input"); - - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); - - tgsi_parse_init(&parse, tokens); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - Storage storage(label_entry, ptr_INPUT); - Instructions instr(mod, shader, label_entry, &storage); - while(!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - translate_declaration(ir, mod, &storage, - &parse.FullToken.FullDeclaration, - &fd); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - translate_immediate(&storage, - &parse.FullToken.FullImmediate); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - translate_instruction(mod, &storage, &instr, - &parse.FullToken.FullInstruction, - &fi, instno); - ++instno; - break; - - default: - assert(0); - } - } - - tgsi_parse_free(&parse); - - ir->num_consts = storage.numConsts(); - return mod; -} - -llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, - const struct tgsi_token *tokens) -{ - llvm::Module *mod = new Module("shader"); - struct tgsi_parse_context parse; - struct tgsi_full_instruction fi; - struct tgsi_full_declaration fd; - unsigned instno = 0; - std::ostringstream stream; - if (ir->type == GALLIVM_VS) { - stream << "vs_shader"; - } else { - stream << "fs_shader"; - } - //stream << ir->id; - std::string func_name = stream.str(); - Function *shader = llvm::cast(mod->getOrInsertFunction( - func_name.c_str(), - vertexShaderFunctionType())); - - Function::arg_iterator args = shader->arg_begin(); - Value *input = args++; - input->setName("inputs"); - Value *output = args++; - output->setName("outputs"); - Value *consts = args++; - consts->setName("consts"); - Value *temps = args++; - temps->setName("temps"); - - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); - - tgsi_parse_init(&parse, tokens); - - fi = tgsi_default_full_instruction(); - fd = tgsi_default_full_declaration(); - - StorageSoa storage(label_entry, input, output, consts, temps); - InstructionsSoa instr(mod, shader, label_entry, &storage); - - while(!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - translate_declarationir(ir, mod, &storage, - &parse.FullToken.FullDeclaration, - &fd); - break; - - case TGSI_TOKEN_TYPE_IMMEDIATE: - translate_immediateir(&storage, - &parse.FullToken.FullImmediate); - break; - - case TGSI_TOKEN_TYPE_INSTRUCTION: - storage.declareImmediates(); - translate_instructionir(mod, &storage, &instr, - &parse.FullToken.FullInstruction, - &fi, instno); - ++instno; - break; - - default: - assert(0); - } - } - - tgsi_parse_free(&parse); - - return mod; -} diff --git a/src/gallium/auxiliary/llvm/tgsitollvm.h b/src/gallium/auxiliary/llvm/tgsitollvm.h deleted file mode 100644 index 7ada04d629..0000000000 --- a/src/gallium/auxiliary/llvm/tgsitollvm.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef TGSITOLLVM_H -#define TGSITOLLVM_H - - -namespace llvm { - class Module; -} - -struct gallivm_ir; -struct tgsi_token; - - -llvm::Module * tgsi_to_llvm(struct gallivm_ir *ir, - const struct tgsi_token *tokens); - - -llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, - const struct tgsi_token *tokens); - -#endif -- cgit v1.2.3 From 0448dbd64a2ef217349f4ada4777d432bc82e46d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 12:33:34 +0000 Subject: Update for llvm -> gallivm rename. --- configs/linux-llvm | 2 +- src/gallium/SConscript | 2 +- src/gallium/auxiliary/draw/draw_vs_llvm.c | 2 +- src/gallium/winsys/xlib/Makefile | 8 ++------ src/mesa/Makefile | 4 ++-- 5 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/configs/linux-llvm b/configs/linux-llvm index a8889321a0..44e200e856 100644 --- a/configs/linux-llvm +++ b/configs/linux-llvm @@ -5,7 +5,7 @@ include $(TOP)/configs/linux CONFIG_NAME = linux-llvm -GALLIUM_AUXILIARY_DIRS += llvm +GALLIUM_AUXILIARY_DIRS += gallivm OPT_FLAGS = -g -ansi -pedantic DEFINES += -DDEBUG -DDEBUG_MATH -DMESA_LLVM=1 diff --git a/src/gallium/SConscript b/src/gallium/SConscript index a835f6d661..ea55ed2ed5 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -13,7 +13,7 @@ SConscript([ 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', 'auxiliary/draw/SConscript', - #'auxiliary/llvm/SConscript', + #'auxiliary/gallivm/SConscript', 'auxiliary/pipebuffer/SConscript', 'drivers/softpipe/SConscript', diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 44022b6e07..0fd557d667 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -40,7 +40,7 @@ #ifdef MESA_LLVM -#include "llvm/gallivm.h" +#include "gallivm/gallivm.h" struct draw_llvm_vertex_shader { struct draw_vertex_shader base; diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 2664ac47ce..17405388ee 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -38,10 +38,6 @@ CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a endif -ifeq ($(CONFIG_NAME), linux-llvm) -LLVM_LIB = $(TOP)/src/gallium/auxiliary/llvm/libgallivm.a -endif - .SUFFIXES : .cpp @@ -69,13 +65,13 @@ STAND_ALONE_OBJECTS = \ $(STAND_ALONE_DRIVER_OBJECTS) # Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(LLVM_LIB) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) $(LLVM_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + --start-group $(PIPE_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) ###################################################################### diff --git a/src/mesa/Makefile b/src/mesa/Makefile index 86a9cf0b88..2403223db2 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -67,13 +67,13 @@ stand-alone: depend subdirs $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$ osmesa-only: depend subdirs $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) # Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(LLVM_LIB) +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) @ $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(LLVM_LIB) $(GL_LIB_DEPS) + $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) # Make the OSMesa library $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) \ -- cgit v1.2.3 From aceeb80d4f706980aaf71b8e098d4c6718d8ac90 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Feb 2008 16:19:05 -0700 Subject: gallium: antialiased line drawing New draw/prim stage: draw_aaline. When installed, lines are replaced by textured quads to do antialiasing. The current user-defined fragment shader is modified to do a texture fetch and modulate fragment alpha. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_aaline.c | 832 ++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_context.c | 22 + src/gallium/auxiliary/draw/draw_context.h | 21 +- src/gallium/auxiliary/draw/draw_prim.c | 7 + src/gallium/auxiliary/draw/draw_private.h | 12 +- src/gallium/auxiliary/draw/draw_validate.c | 8 +- src/gallium/auxiliary/tgsi/Makefile | 1 + src/gallium/drivers/softpipe/sp_context.c | 3 + src/gallium/drivers/softpipe/sp_state_derived.c | 17 +- 10 files changed, 914 insertions(+), 10 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_aaline.c (limited to 'src') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index c56b63d85b..c8000cbe9c 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = draw DRIVER_SOURCES = \ + draw_aaline.c \ draw_clip.c \ draw_vs_exec.c \ draw_vs_sse.c \ diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c new file mode 100644 index 0000000000..f1fee4f8ba --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -0,0 +1,832 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * AA line stage: AA lines are converted to texture mapped triangles. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + +/** + * Max texture level for the alpha texture used for antialiasing + */ +#define MAX_TEXTURE_LEVEL 5 /* 32 x 32 */ + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct aaline_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; + void *aaline_fs; + void *aapoint_fs; /* not yet */ + void *sprite_fs; /* not yet */ +}; + + +/** + * Subclass of draw_stage + */ +struct aaline_stage +{ + struct draw_stage stage; + + float half_line_width; + + /** For AA lines, this is the vertex attrib slot for the new texcoords */ + uint tex_slot; + + void *sampler_cso; + struct pipe_texture *texture; + uint sampler_unit; + + + /* + * Currently bound state + */ + struct aaline_fragment_shader *fs; + struct { + void *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + } state; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *); + + void (*driver_set_sampler_texture)(struct pipe_context *, + unsigned sampler, + struct pipe_texture *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct aa_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int colorOutput; /**< which output is the primary color */ + int maxSampler; /**< max sampler index found */ + int maxInput, maxGeneric; /**< max input index found */ + int colorTemp, texTemp; /**< temp registers */ + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +aa_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && + decl->Semantic.SemanticIndex == 0) { + aactx->colorOutput = decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + if (decl->u.DeclarationRange.Last > aactx->maxSampler) + aactx->maxSampler = decl->u.DeclarationRange.Last + 1; + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + if (decl->u.DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->u.DeclarationRange.Last; + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + decl->Semantic.SemanticIndex > aactx->maxGeneric) { + aactx->maxGeneric = decl->Semantic.SemanticIndex; + } + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +aa_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (aactx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + uint i; + + /* find two free temp regs */ + for (i = 0; i < 32; i++) { + if ((aactx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (aactx->colorTemp < 0) + aactx->colorTemp = i; + else if (aactx->texTemp < 0) + aactx->texTemp = i; + else + break; + } + } + assert(aactx->colorTemp >= 0); + assert(aactx->texTemp >= 0); + + /* declare new generic input/texcoord */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; + decl.Declaration.Interpolate = 1; + /* XXX this could be linear... */ + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->maxInput + 1; + ctx->emit_declaration(ctx, &decl); + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->maxSampler + 1; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->texTemp; + ctx->emit_declaration(ctx, &decl); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->colorTemp; + ctx->emit_declaration(ctx, &decl); + + aactx->firstInstruction = FALSE; + } + + if (inst->Instruction.Opcode == TGSI_OPCODE_END && + aactx->colorOutput != -1) { + struct tgsi_full_instruction newInst; + + /* TEX */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->maxSampler + 1; + + ctx->emit_instruction(ctx, &newInst); + + /* MOV rgb */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + ctx->emit_instruction(ctx, &newInst); + + /* MUL alpha */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp; + ctx->emit_instruction(ctx, &newInst); + + /* END */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_END; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 0; + ctx->emit_instruction(ctx, &newInst); + } + else { + /* Not an END instruction. + * Look for writes to result.color and replace with colorTemp reg. + */ + uint i; + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + if (dst->DstRegister.File == TGSI_FILE_OUTPUT && + dst->DstRegister.Index == aactx->colorOutput) { + dst->DstRegister.File = TGSI_FILE_TEMPORARY; + dst->DstRegister.Index = aactx->colorTemp; + } + } + + ctx->emit_instruction(ctx, inst); + } +} + + +/** + * Generate the frag shader we'll use for drawing AA lines. + * This will be the user's shader plus some texture/modulate instructions. + */ +static void +generate_aaline_fs(struct aaline_stage *aaline) +{ + const struct pipe_shader_state *orig_fs = &aaline->fs->state; + struct draw_context *draw = aaline->stage.draw; + struct pipe_shader_state aaline_fs; + struct aa_transform_context transform; + +#define MAX 1000 + + aaline_fs = *orig_fs; /* copy to init */ + aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.colorOutput = -1; + transform.maxSampler = -1; + transform.maxInput = -1; + transform.maxGeneric = -1; + transform.colorTemp = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = aa_transform_inst; + transform.base.transform_declaration = aa_transform_decl; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) aaline_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(aaline_fs.tokens, 0); +#endif + + aaline_fs.input_semantic_name[aaline_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; + aaline_fs.input_semantic_index[aaline_fs.num_inputs] = transform.maxGeneric + 1; + aaline_fs.num_inputs++; + + aaline->fs->aaline_fs + = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); + + /* advertise the extra post-transform vertex attributes which will have + * the texcoords. + */ + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = transform.maxGeneric + 1; +} + + +/** + * Create the texture map we'll use for antialiasing the lines. + */ +static void +aaline_create_texture(struct aaline_stage *aaline) +{ + struct pipe_context *pipe = aaline->pipe; + struct pipe_texture texTemp; + uint level; + + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.last_level = MAX_TEXTURE_LEVEL; + texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; + texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; + texTemp.depth[0] = 1; + texTemp.cpp = 1; + + aaline->texture = pipe->texture_create(pipe, &texTemp); + + /* Fill in mipmap images. + * Basically each level is solid opaque, except for the outermost + * texels which are zero. Special case the 1x1 and 2x2 levels. + */ + for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { + struct pipe_surface *surface; + const uint size = aaline->texture->width[level]; + ubyte *data; + uint i, j; + + assert(aaline->texture->width[level] == aaline->texture->height[level]); + + surface = pipe->get_tex_surface(pipe, aaline->texture, 0, level, 0); + data = pipe_surface_map(surface); + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + uint d; + if (size == 1) { + d = 255; + } + else if (size == 2) { + d = 200; /* tuneable */ + } + else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { + d = 0; + } + else { + d = 255; + } + data[i * surface->pitch + j] = d; + } + } + + /* unmap */ + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + } +} + + +/** + * Create the sampler CSO that'll be used for antialiasing. + * By using a mipmapped texture, we don't have to generate a different + * texture image for each line size. + */ +static void +aaline_create_sampler(struct aaline_stage *aaline) +{ + struct pipe_sampler_state sampler; + struct pipe_context *pipe = aaline->pipe; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.normalized_coords = 1; + sampler.min_lod = 0.0f; + sampler.max_lod = MAX_TEXTURE_LEVEL; + + aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler); +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_aaline_fragment_shader(struct aaline_stage *aaline) +{ + if (!aaline->fs->aaline_fs) { + generate_aaline_fs(aaline); + } + aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); +} + + + +static INLINE struct aaline_stage * +aaline_stage( struct draw_stage *stage ) +{ + return (struct aaline_stage *) stage; +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad, using geometry which will + * fullfill GL's antialiased line requirements. + */ +static void +aaline_line(struct draw_stage *stage, struct prim_header *header) +{ + const struct aaline_stage *aaline = aaline_stage(stage); + const float half_width = aaline->half_line_width; + struct prim_header tri; + struct vertex_header *v[8]; + uint texPos = aaline->tex_slot; + float *pos, *tex; + float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; + float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; + float a = atan2(dy, dx); + float c_a = cos(a), s_a = sin(a); + uint i; + + /* XXX the ends of lines aren't quite perfect yet, but probably passable */ + dx = 0.5 * half_width; + dy = half_width; + + /* allocate/dup new verts */ + for (i = 0; i < 8; i++) { + v[i] = dup_vert(stage, header->v[i/4], i); + } + + /* + * Quad strip for line from v0 to v1 (*=endpoints): + * + * 1 3 5 7 + * +---+---------------------+---+ + * | | + * | *v0 v1* | + * | | + * +---+---------------------+---+ + * 0 2 4 6 + */ + + /* new verts */ + pos = v[0]->data[0]; + pos[0] += (-dx * c_a - dy * s_a); + pos[1] += (-dx * s_a + dy * c_a); + + pos = v[1]->data[0]; + pos[0] += (-dx * c_a - -dy * s_a); + pos[1] += (-dx * s_a + -dy * c_a); + + pos = v[2]->data[0]; + pos[0] += ( dx * c_a - dy * s_a); + pos[1] += ( dx * s_a + dy * c_a); + + pos = v[3]->data[0]; + pos[0] += ( dx * c_a - -dy * s_a); + pos[1] += ( dx * s_a + -dy * c_a); + + pos = v[4]->data[0]; + pos[0] += (-dx * c_a - dy * s_a); + pos[1] += (-dx * s_a + dy * c_a); + + pos = v[5]->data[0]; + pos[0] += (-dx * c_a - -dy * s_a); + pos[1] += (-dx * s_a + -dy * c_a); + + pos = v[6]->data[0]; + pos[0] += ( dx * c_a - dy * s_a); + pos[1] += ( dx * s_a + dy * c_a); + + pos = v[7]->data[0]; + pos[0] += ( dx * c_a - -dy * s_a); + pos[1] += ( dx * s_a + -dy * c_a); + + /* new texcoords */ + tex = v[0]->data[texPos]; + ASSIGN_4V(tex, 0, 0, 0, 1); + + tex = v[1]->data[texPos]; + ASSIGN_4V(tex, 0, 1, 0, 1); + + tex = v[2]->data[texPos]; + ASSIGN_4V(tex, .5, 0, 0, 1); + + tex = v[3]->data[texPos]; + ASSIGN_4V(tex, .5, 1, 0, 1); + + tex = v[4]->data[texPos]; + ASSIGN_4V(tex, .5, 0, 0, 1); + + tex = v[5]->data[texPos]; + ASSIGN_4V(tex, .5, 1, 0, 1); + + tex = v[6]->data[texPos]; + ASSIGN_4V(tex, 1, 0, 0, 1); + + tex = v[7]->data[texPos]; + ASSIGN_4V(tex, 1, 1, 0, 1); + + /* emit 6 tris for the quad strip */ + tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[4]; tri.v[1] = v[3]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[5]; tri.v[1] = v[3]; tri.v[2] = v[4]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[6]; tri.v[1] = v[5]; tri.v[2] = v[4]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[7]; tri.v[1] = v[5]; tri.v[2] = v[6]; + stage->next->tri( stage->next, &tri ); +} + + +static void +aaline_first_line(struct draw_stage *stage, struct prim_header *header) +{ + auto struct aaline_stage *aaline = aaline_stage(stage); + struct draw_context *draw = stage->draw; + struct pipe_context *pipe = aaline->pipe; + + assert(draw->rasterizer->line_smooth); + + if (draw->rasterizer->line_width <= 3.0) + aaline->half_line_width = 1.5f; + else + aaline->half_line_width = 0.5f * draw->rasterizer->line_width; + + aaline->tex_slot = draw->num_vs_outputs; + assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ + draw->extra_vp_outputs.slot = aaline->tex_slot; + + /* + * Bind our fragprog, sampler and texture + */ + bind_aaline_fragment_shader(aaline); + + aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, aaline->sampler_cso); + aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, aaline->texture); + + /* now really draw first line */ + stage->line = aaline_line; + stage->line(stage, header); +} + + +static void +aaline_flush(struct draw_stage *stage, unsigned flags) +{ + struct draw_context *draw = stage->draw; + struct aaline_stage *aaline = aaline_stage(stage); + struct pipe_context *pipe = aaline->pipe; + + stage->line = aaline_first_line; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); + + /* XXX restore original texture, sampler state */ + aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, + aaline->state.sampler[aaline->sampler_unit]); + aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, + aaline->state.texture[aaline->sampler_unit]); + + draw->extra_vp_outputs.slot = 0; +} + + +static void +aaline_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +aaline_destroy(struct draw_stage *stage) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct aaline_stage * +draw_aaline_stage(struct draw_context *draw) +{ + struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); + + draw_alloc_temp_verts( &aaline->stage, 8 ); + + aaline->stage.draw = draw; + aaline->stage.next = NULL; + aaline->stage.point = passthrough_point; + aaline->stage.line = aaline_first_line; + aaline->stage.tri = passthrough_tri; + aaline->stage.flush = aaline_flush; + aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; + aaline->stage.destroy = aaline_destroy; + + return aaline; +} + + +/* + * XXX temporary? solution to mapping a pipe_context to a aaline_stage. + */ + +#define MAX_CONTEXTS 10 + +static struct pipe_context *Pipe[MAX_CONTEXTS]; +static struct aaline_stage *Stage[MAX_CONTEXTS]; +static uint NumContexts; + +static void +add_aa_pipe_context(struct pipe_context *pipe, struct aaline_stage *aa) +{ + assert(NumContexts < MAX_CONTEXTS); + Pipe[NumContexts] = pipe; + Stage[NumContexts] = aa; + NumContexts++; +} + +static struct aaline_stage * +aaline_stage_from_pipe(struct pipe_context *pipe) +{ + uint i; + for (i = 0; i < NumContexts; i++) { + if (Pipe[i] == pipe) + return Stage[i]; + } + assert(0); + return NULL; +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +aaline_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); + } + + return aafs; +} + + +static void +aaline_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* save current */ + aaline->fs = aafs; + /* pass-through */ + aaline->driver_bind_fs_state(aaline->pipe, aafs->driver_fs); +} + + +static void +aaline_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* pass-through */ + aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs); + FREE(aafs); +} + + +static void +aaline_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + /* save current */ + aaline->state.sampler[unit] = sampler; + /* pass-through */ + aaline->driver_bind_sampler_state(aaline->pipe, unit, sampler); +} + + +static void +aaline_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, struct pipe_texture *texture) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + /* save current */ + aaline->state.texture[sampler] = texture; + /* pass-through */ + aaline->driver_set_sampler_texture(aaline->pipe, sampler, texture); +} + + +/** + * Called by drivers that want to install this AA line prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA lines. + */ +void +draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) +{ + struct aaline_stage *aaline; + + /* + * Create / install AA line drawing / prim stage + */ + aaline = draw_aaline_stage( draw ); + assert(aaline); + draw->pipeline.aaline = &aaline->stage; + + aaline->pipe = pipe; + + /* create special texture, sampler state */ + aaline_create_texture(aaline); + aaline_create_sampler(aaline); + + /* save original driver functions */ + aaline->driver_create_fs_state = pipe->create_fs_state; + aaline->driver_bind_fs_state = pipe->bind_fs_state; + aaline->driver_delete_fs_state = pipe->delete_fs_state; + + aaline->driver_bind_sampler_state = pipe->bind_sampler_state; + aaline->driver_set_sampler_texture = pipe->set_sampler_texture; + + /* override the driver's functions */ + pipe->create_fs_state = aaline_create_fs_state; + pipe->bind_fs_state = aaline_bind_fs_state; + pipe->delete_fs_state = aaline_delete_fs_state; + + pipe->bind_sampler_state = aaline_bind_sampler_state; + pipe->set_sampler_texture = aaline_set_sampler_texture; + + add_aa_pipe_context(pipe, aaline); +} diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 4be3830316..a7f3b4aecb 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -103,6 +103,8 @@ void draw_destroy( struct draw_context *draw ) draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); draw->pipeline.cull->destroy( draw->pipeline.cull ); draw->pipeline.validate->destroy( draw->pipeline.validate ); + if (draw->pipeline.aaline) + draw->pipeline.aaline->destroy( draw->pipeline.aaline ); if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); tgsi_exec_machine_free_data(&draw->machine); @@ -239,6 +241,26 @@ draw_convert_wide_lines(struct draw_context *draw, boolean enable) } +/** + * The draw module may sometimes generate vertices with extra attributes + * (such as texcoords for AA lines). The driver can call this function + * to find those attributes. + */ +int +draw_find_vs_output(struct draw_context *draw, + uint semantic_name, uint semantic_index) +{ + /* XXX there may be more than one extra vertex attrib. + * For example, simulated gl_FragCoord and gl_PointCoord. + */ + if (draw->extra_vp_outputs.semantic_name == semantic_name && + draw->extra_vp_outputs.semantic_index == semantic_index) { + return draw->extra_vp_outputs.slot; + } + return 0; +} + + /** * Allocate space for temporary post-transform vertices, such as for clipping. */ diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index ddeb184497..82035aa8ad 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -41,6 +41,7 @@ #include "pipe/p_state.h" +struct pipe_context; struct vertex_buffer; struct vertex_info; struct draw_context; @@ -93,6 +94,20 @@ void draw_convert_wide_points(struct draw_context *draw, boolean enable); void draw_convert_wide_lines(struct draw_context *draw, boolean enable); +boolean draw_use_sse(struct draw_context *draw); + +void +draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); + + +int +draw_find_vs_output(struct draw_context *draw, + uint semantic_name, uint semantic_index); + + +/* + * Vertex shader functions + */ struct draw_vertex_shader * draw_create_vertex_shader(struct draw_context *draw, @@ -102,7 +117,11 @@ void draw_bind_vertex_shader(struct draw_context *draw, void draw_delete_vertex_shader(struct draw_context *draw, struct draw_vertex_shader *dvs); -boolean draw_use_sse(struct draw_context *draw); + + +/* + * Vertex data functions + */ void draw_set_vertex_buffer(struct draw_context *draw, unsigned attr, diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 51e2242719..dd9a848863 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -121,11 +121,15 @@ static void draw_prim_queue_flush( struct draw_context *draw ) void draw_do_flush( struct draw_context *draw, unsigned flags ) { + static boolean flushing = FALSE; + if (0) debug_printf("Flushing with %d verts, %d prims\n", draw->vs.queue_nr, draw->pq.queue_nr ); + if (!flushing) { + flushing = TRUE; if (flags >= DRAW_FLUSH_SHADER_QUEUE) { if (draw->vs.queue_nr) @@ -146,6 +150,9 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) } } } + + flushing = FALSE; + } } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index bc11259cb2..dd75f9aefc 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -48,6 +48,7 @@ #include "tgsi/exec/tgsi_exec.h" +struct pipe_context; struct gallivm_prog; struct gallivm_cpu_engine; @@ -179,6 +180,7 @@ struct draw_context struct draw_stage *offset; struct draw_stage *unfilled; struct draw_stage *stipple; + struct draw_stage *aaline; struct draw_stage *wide; struct draw_stage *rasterize; } pipeline; @@ -212,9 +214,17 @@ struct draw_context unsigned nr_planes; boolean convert_wide_points; /**< convert wide points to tris? */ - boolean convert_wide_lines; /**< convert side lines to tris? */ + boolean convert_wide_lines; /**< convert wide lines to tris? */ boolean use_sse; + /* If a prim stage introduces new vertex attributes, they'll be stored here + */ + struct { + uint semantic_name; + uint semantic_index; + int slot; + } extra_vp_outputs; + unsigned reduced_prim; /** TGSI program interpreter runtime state */ diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 4375ebabbc..97e40e372b 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -58,7 +58,13 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) * shorter pipelines for lines & points. */ - if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines) || + if (draw->rasterizer->line_smooth && draw->pipeline.aaline) { + draw->pipeline.aaline->next = next; + next = draw->pipeline.aaline; + } + + if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines + && !draw->rasterizer->line_smooth) || (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || draw->rasterizer->point_sprite) { draw->pipeline.wide->next = next; diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index c10ab396d8..8bb62b2a0a 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -10,6 +10,7 @@ DRIVER_SOURCES = \ util/tgsi_build.c \ util/tgsi_dump.c \ util/tgsi_parse.c \ + util/tgsi_transform.c \ util/tgsi_util.c C_SOURCES = \ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 5e98f190bb..254c6adca4 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -327,6 +327,9 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, draw_set_rasterize_stage(softpipe->draw, softpipe->setup); } + /* enable aaline stage */ + draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); + sp_init_surface_functions(softpipe); return &softpipe->pipe; diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c index 9d8fd8b750..f9f2c5eaa8 100644 --- a/src/gallium/drivers/softpipe/sp_state_derived.c +++ b/src/gallium/drivers/softpipe/sp_state_derived.c @@ -44,7 +44,8 @@ * condition that users shouldn't hit anyway. */ static int -find_vs_output(const struct pipe_shader_state *vs, +find_vs_output(struct softpipe_context *sp, + const struct pipe_shader_state *vs, uint semantic_name, uint semantic_index) { @@ -54,7 +55,9 @@ find_vs_output(const struct pipe_shader_state *vs, vs->output_semantic_index[i] == semantic_index) return i; } - return 0; + + /* See if the draw module is introducing a new attribute... */ + return draw_find_vs_output(sp->draw, semantic_name, semantic_index); } @@ -111,24 +114,24 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) int src; switch (fs->input_semantic_name[i]) { case TGSI_SEMANTIC_POSITION: - src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0); + src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_POSITION, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); break; case TGSI_SEMANTIC_COLOR: - src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, + src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_COLOR, fs->input_semantic_index[i]); draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); break; case TGSI_SEMANTIC_FOG: - src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0); + src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_FOG, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ - src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC, + src = find_vs_output(softpipe, vs, TGSI_SEMANTIC_GENERIC, fs->input_semantic_index[i]); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); break; @@ -138,7 +141,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe) } } - softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0); + softpipe->psize_slot = find_vs_output(softpipe, vs, TGSI_SEMANTIC_PSIZE, 0); if (softpipe->psize_slot > 0) { draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, softpipe->psize_slot); -- cgit v1.2.3 From 478c14453b33b20724bcdb70cf1f54f4addb71ab Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Feb 2008 16:50:07 -0700 Subject: gallium: remove the prototype/unused wide_line_aa() function --- src/gallium/auxiliary/draw/draw_wide_prims.c | 69 +--------------------------- 1 file changed, 1 insertion(+), 68 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_wide_prims.c b/src/gallium/auxiliary/draw/draw_wide_prims.c index 655774b155..1f8069bdca 100644 --- a/src/gallium/auxiliary/draw/draw_wide_prims.c +++ b/src/gallium/auxiliary/draw/draw_wide_prims.c @@ -161,70 +161,6 @@ static void wide_line( struct draw_stage *stage, } -/** - * Draw a wide line by drawing a quad, using geometry which will - * fullfill GL's antialiased line requirements. - */ -static void wide_line_aa(struct draw_stage *stage, - struct prim_header *header) -{ - const struct wide_stage *wide = wide_stage(stage); - const float half_width = wide->half_line_width; - struct prim_header tri; - struct vertex_header *v[4]; - float *pos; - float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; - float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; - const float len = (float) sqrt(dx * dx + dy * dy); - uint i; - - dx = dx * half_width / len; - dy = dy * half_width / len; - - /* allocate/dup new verts */ - for (i = 0; i < 4; i++) { - v[i] = dup_vert(stage, header->v[i/2], i); - } - - /* - * Quad for line from v0 to v1: - * - * 1 3 - * +-------------------------+ - * | | - * *v0 v1* - * | | - * +-------------------------+ - * 0 2 - */ - - pos = v[0]->data[0]; - pos[0] += dy; - pos[1] -= dx; - - pos = v[1]->data[0]; - pos[0] -= dy; - pos[1] += dx; - - pos = v[2]->data[0]; - pos[0] += dy; - pos[1] -= dx; - - pos = v[3]->data[0]; - pos[0] -= dy; - pos[1] += dx; - - tri.det = header->det; /* only the sign matters */ - - tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - -} - - /** * Set the vertex texcoords for sprite mode. * Coords may be left untouched or set to a right-side-up or upside-down @@ -379,10 +315,7 @@ static void wide_first_line( struct draw_stage *stage, wide->half_line_width = 0.5f * draw->rasterizer->line_width; if (draw->rasterizer->line_width != 1.0) { - if (draw->rasterizer->line_smooth) - wide->stage.line = wide_line_aa; - else - wide->stage.line = wide_line; + wide->stage.line = wide_line; } else { wide->stage.line = passthrough_line; -- cgit v1.2.3 From ae9931dad24703d99530b2761c759cef1cbc0fb5 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Feb 2008 18:36:20 -0700 Subject: gallium: call draw_flush() for scissor/stipple state changes --- src/gallium/drivers/softpipe/sp_state_clip.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c index c797c0dd3b..d8ea979957 100644 --- a/src/gallium/drivers/softpipe/sp_state_clip.c +++ b/src/gallium/drivers/softpipe/sp_state_clip.c @@ -68,6 +68,8 @@ void softpipe_set_scissor_state( struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); + draw_flush(softpipe->draw); + memcpy( &softpipe->scissor, scissor, sizeof(*scissor) ); softpipe->dirty |= SP_NEW_SCISSOR; } @@ -78,6 +80,8 @@ void softpipe_set_polygon_stipple( struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); + draw_flush(softpipe->draw); + memcpy( &softpipe->poly_stipple, stipple, sizeof(*stipple) ); softpipe->dirty |= SP_NEW_STIPPLE; } -- cgit v1.2.3 From 6c7f663cb96cac4873129f835614181405bd3f6e Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Feb 2008 18:39:55 -0700 Subject: gallium: move draw_set_viewport_state() call, plus code clean-up, remove obsolete comments --- src/gallium/drivers/softpipe/sp_state_clip.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_state_clip.c b/src/gallium/drivers/softpipe/sp_state_clip.c index d8ea979957..4946c776e3 100644 --- a/src/gallium/drivers/softpipe/sp_state_clip.c +++ b/src/gallium/drivers/softpipe/sp_state_clip.c @@ -42,24 +42,16 @@ void softpipe_set_clip_state( struct pipe_context *pipe, } - -/* Called when driver state tracker notices changes to the viewport - * matrix: - */ void softpipe_set_viewport_state( struct pipe_context *pipe, const struct pipe_viewport_state *viewport ) { struct softpipe_context *softpipe = softpipe_context(pipe); - softpipe->viewport = *viewport; /* struct copy */ - softpipe->dirty |= SP_NEW_VIEWPORT; - /* pass the viewport info to the draw module */ draw_set_viewport_state(softpipe->draw, viewport); - /* Using tnl/ and vf/ modules is temporary while getting started. - * Full pipe will have vertex shader, vertex fetch of its own. - */ + softpipe->viewport = *viewport; /* struct copy */ + softpipe->dirty |= SP_NEW_VIEWPORT; } @@ -70,7 +62,7 @@ void softpipe_set_scissor_state( struct pipe_context *pipe, draw_flush(softpipe->draw); - memcpy( &softpipe->scissor, scissor, sizeof(*scissor) ); + softpipe->scissor = *scissor; /* struct copy */ softpipe->dirty |= SP_NEW_SCISSOR; } @@ -82,6 +74,6 @@ void softpipe_set_polygon_stipple( struct pipe_context *pipe, draw_flush(softpipe->draw); - memcpy( &softpipe->poly_stipple, stipple, sizeof(*stipple) ); + softpipe->poly_stipple = *stipple; /* struct copy */ softpipe->dirty |= SP_NEW_STIPPLE; } -- cgit v1.2.3 From e279b1c57ac8d17703d80f1b644fd1d4f115101b Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 14:35:19 +0000 Subject: More llvm -> gallivm. Forgot this one on the last commit. --- src/gallium/drivers/cell/ppu/cell_state_fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_fs.c index b2ed699a5b..f3958fa429 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_fs.c +++ b/src/gallium/drivers/cell/ppu/cell_state_fs.c @@ -32,7 +32,7 @@ #include "draw/draw_context.h" #if 0 #include "pipe/p_shader_tokens.h" -#include "llvm/gallivm.h" +#include "gallivm/gallivm.h" #include "tgsi/util/tgsi_dump.h" #include "tgsi/exec/tgsi_sse2.h" #endif -- cgit v1.2.3 From e773a813cf475e2a7ad79ea1ec698bf2530d0433 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 10:50:39 +0900 Subject: Initial scons support to build gallivm. Not yet complete. --- SConstruct | 13 +++++++++++++ src/gallium/SConscript | 6 +++++- src/gallium/auxiliary/gallivm/SConscript | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/gallivm/SConscript (limited to 'src') diff --git a/SConstruct b/SConstruct index 4fb51f2e6d..b20f88a303 100644 --- a/SConstruct +++ b/SConstruct @@ -32,6 +32,7 @@ import sys opts = Options('config.py') opts.Add(BoolOption('debug', 'build debug version', False)) opts.Add(BoolOption('dri', 'build dri drivers', False)) +opts.Add(BoolOption('llvm', 'use llvm', False)) opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86', allowed_values=('generic', 'x86', 'x86-64'))) @@ -55,6 +56,7 @@ else: # replicate options values in local variables debug = env['debug'] dri = env['dri'] +llvm = env['llvm'] machine = env['machine'] # derived options @@ -66,6 +68,7 @@ Export([ 'debug', 'x86', 'dri', + 'llvm', 'platform', 'gcc', 'msvc', @@ -159,6 +162,14 @@ if dri: 'GLX_INDIRECT_RENDERING', ]) +# LLVM +if llvm: + # See also http://www.scons.org/wiki/UsingPkgConfig + env.ParseConfig('llvm-config --cflags --ldflags --libs') + env.Append(CPPDEFINES = ['MESA_LLVM']) + env.Append(CXXFLAGS = ['-Wno-long-long']) + + # libGL if 1: env.Append(LIBS = [ @@ -214,6 +225,8 @@ build_topdir = 'build' build_subdir = platform if dri: build_subdir += "-dri" +if llvm: + build_subdir += "-llvm" if x86: build_subdir += "-x86" if debug: diff --git a/src/gallium/SConscript b/src/gallium/SConscript index ea55ed2ed5..c505eee792 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -13,9 +13,13 @@ SConscript([ 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', 'auxiliary/draw/SConscript', - #'auxiliary/gallivm/SConscript', 'auxiliary/pipebuffer/SConscript', +]) + +if llvm: + SConscript(['auxiliary/gallivm/SConscript']) +SConscript([ 'drivers/softpipe/SConscript', 'drivers/i915simple/SConscript', 'drivers/i965simple/SConscript', diff --git a/src/gallium/auxiliary/gallivm/SConscript b/src/gallium/auxiliary/gallivm/SConscript new file mode 100644 index 0000000000..c0aa51b90a --- /dev/null +++ b/src/gallium/auxiliary/gallivm/SConscript @@ -0,0 +1,16 @@ +Import('*') + +gallivm = env.ConvenienceLibrary( + target = 'gallivm', + source = [ + 'gallivm.cpp', + 'gallivm_cpu.cpp', + 'instructions.cpp', + 'loweringpass.cpp', + 'tgsitollvm.cpp', + 'storage.cpp', + 'storagesoa.cpp', + 'instructionssoa.cpp', + ]) + +auxiliaries.insert(0, gallivm) -- cgit v1.2.3 From df8ab3140ce05599e1dc983ac211a30fc845d9b5 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 11:49:48 +0900 Subject: Bring rtasm from mesa to gallium. --- configs/default | 2 +- src/gallium/SConscript | 1 + src/gallium/auxiliary/rtasm/Makefile | 20 + src/gallium/auxiliary/rtasm/SConscript | 11 + src/gallium/auxiliary/rtasm/execmem.c | 133 ++++ src/gallium/auxiliary/rtasm/execmem.h | 45 ++ src/gallium/auxiliary/rtasm/mm.c | 283 ++++++++ src/gallium/auxiliary/rtasm/mm.h | 89 +++ src/gallium/auxiliary/rtasm/x86sse.c | 1195 ++++++++++++++++++++++++++++++++ src/gallium/auxiliary/rtasm/x86sse.h | 256 +++++++ 10 files changed, 2034 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/rtasm/Makefile create mode 100644 src/gallium/auxiliary/rtasm/SConscript create mode 100644 src/gallium/auxiliary/rtasm/execmem.c create mode 100644 src/gallium/auxiliary/rtasm/execmem.h create mode 100644 src/gallium/auxiliary/rtasm/mm.c create mode 100644 src/gallium/auxiliary/rtasm/mm.h create mode 100644 src/gallium/auxiliary/rtasm/x86sse.c create mode 100644 src/gallium/auxiliary/rtasm/x86sse.h (limited to 'src') diff --git a/configs/default b/configs/default index 7f659725cb..c9be5ec3e3 100644 --- a/configs/default +++ b/configs/default @@ -68,7 +68,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos # Gallium directories and -GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi util +GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi rtasm util GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) diff --git a/src/gallium/SConscript b/src/gallium/SConscript index c505eee792..a08b4b830e 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -10,6 +10,7 @@ Export('auxiliaries') SConscript([ # NOTE: order matters! 'auxiliary/util/SConscript', + 'auxiliary/rtasm/SConscript', 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', 'auxiliary/draw/SConscript', diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile new file mode 100644 index 0000000000..b3b9934e10 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -0,0 +1,20 @@ + +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = rtasm + +DRIVER_SOURCES = \ + x86sse.c \ + mm.c \ + execmem.c + +C_SOURCES = \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript new file mode 100644 index 0000000000..c5b1551786 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -0,0 +1,11 @@ +Import('*') + +rtasm = env.ConvenienceLibrary( + target = 'rtasm', + source = [ + 'x86sse.c', + 'mm.c', + 'execmem.c', + ]) + +auxiliaries.insert(0, rtasm) diff --git a/src/gallium/auxiliary/rtasm/execmem.c b/src/gallium/auxiliary/rtasm/execmem.c new file mode 100644 index 0000000000..c7c35f7ef2 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/execmem.c @@ -0,0 +1,133 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * \file exemem.c + * Functions for allocating executable memory. + * + * \author Keith Whitwell + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_thread.h" + +#include "execmem.h" + + +#if defined(__linux__) + +/* + * Allocate a large block of memory which can hold code then dole it out + * in pieces by means of the generic memory manager code. +*/ + +#include +#include +#include "mm.h" + +#define EXEC_HEAP_SIZE (10*1024*1024) + +_glthread_DECLARE_STATIC_MUTEX(exec_mutex); + +static struct mem_block *exec_heap = NULL; +static unsigned char *exec_mem = NULL; + + +static void +init_heap(void) +{ + if (!exec_heap) + exec_heap = mmInit( 0, EXEC_HEAP_SIZE ); + + if (!exec_mem) + exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +} + + +void * +_mesa_exec_malloc(size_t size) +{ + struct mem_block *block = NULL; + void *addr = NULL; + + _glthread_LOCK_MUTEX(exec_mutex); + + init_heap(); + + if (exec_heap) { + size = (size + 31) & ~31; + block = mmAllocMem( exec_heap, size, 32, 0 ); + } + + if (block) + addr = exec_mem + block->ofs; + else + debug_printf("_mesa_exec_malloc failed\n"); + + _glthread_UNLOCK_MUTEX(exec_mutex); + + return addr; +} + + +void +_mesa_exec_free(void *addr) +{ + _glthread_LOCK_MUTEX(exec_mutex); + + if (exec_heap) { + struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); + + if (block) + mmFreeMem(block); + } + + _glthread_UNLOCK_MUTEX(exec_mutex); +} + + +#else + +/* + * Just use regular memory. + */ + +void * +_mesa_exec_malloc(GLuint size) +{ + return _mesa_malloc( size ); +} + + +void +_mesa_exec_free(void *addr) +{ + _mesa_free(addr); +} + + +#endif diff --git a/src/gallium/auxiliary/rtasm/execmem.h b/src/gallium/auxiliary/rtasm/execmem.h new file mode 100644 index 0000000000..9fd4569165 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/execmem.h @@ -0,0 +1,45 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file exemem.c + * Functions for allocating executable memory. + * + * \author Keith Whitwell + */ + +#ifndef _EXECMEM_H_ +#define _EXECMEM_H_ + +#include "pipe/p_compiler.h" + + +extern void * +_mesa_exec_malloc( size_t size ); + + +extern void +_mesa_exec_free( void *addr ); + + +#endif diff --git a/src/gallium/auxiliary/rtasm/mm.c b/src/gallium/auxiliary/rtasm/mm.c new file mode 100644 index 0000000000..15f50491da --- /dev/null +++ b/src/gallium/auxiliary/rtasm/mm.c @@ -0,0 +1,283 @@ +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * 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 + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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 "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" + +#include "mm.h" + + +void +mmDumpMemInfo(const struct mem_block *heap) +{ + debug_printf("Memory heap %p:\n", (void *)heap); + if (heap == 0) { + debug_printf(" heap == 0\n"); + } else { + const struct mem_block *p; + + for(p = heap->next; p != heap; p = p->next) { + debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + debug_printf("\nFree list:\n"); + + for(p = heap->next_free; p != heap; p = p->next_free) { + debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + } + debug_printf("End of memory blocks\n"); +} + +struct mem_block * +mmInit(int ofs, int size) +{ + struct mem_block *heap, *block; + + if (size <= 0) + return NULL; + + heap = CALLOC_STRUCT(mem_block); + if (!heap) + return NULL; + + block = CALLOC_STRUCT(mem_block); + if (!block) { + FREE(heap); + return NULL; + } + + heap->next = block; + heap->prev = block; + heap->next_free = block; + heap->prev_free = block; + + block->heap = heap; + block->next = heap; + block->prev = heap; + block->next_free = heap; + block->prev_free = heap; + + block->ofs = ofs; + block->size = size; + block->free = 1; + + return heap; +} + + +static struct mem_block * +SliceBlock(struct mem_block *p, + int startofs, int size, + int reserved, int alignment) +{ + struct mem_block *newblock; + + /* break left [p, newblock, p->next], then p = newblock */ + if (startofs > p->ofs) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size -= newblock->size; + p = newblock; + } + + /* break right, also [p, newblock, p->next] */ + if (size < p->size) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size = size; + } + + /* p = middle block */ + p->free = 0; + + /* Remove p from the free list: + */ + p->next_free->prev_free = p->prev_free; + p->prev_free->next_free = p->next_free; + + p->next_free = 0; + p->prev_free = 0; + + p->reserved = reserved; + return p; +} + + +struct mem_block * +mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) +{ + struct mem_block *p; + const int mask = (1 << align2)-1; + int startofs = 0; + int endofs; + + if (!heap || align2 < 0 || size <= 0) + return NULL; + + for (p = heap->next_free; p != heap; p = p->next_free) { + assert(p->free); + + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; + } + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; + } + + if (p == heap) + return NULL; + + assert(p->free); + p = SliceBlock(p,startofs,size,0,mask+1); + + return p; +} + + +struct mem_block * +mmFindBlock(struct mem_block *heap, int start) +{ + struct mem_block *p; + + for (p = heap->next; p != heap; p = p->next) { + if (p->ofs == start) + return p; + } + + return NULL; +} + + +static INLINE int +Join2Blocks(struct mem_block *p) +{ + /* XXX there should be some assertions here */ + + /* NOTE: heap->free == 0 */ + + if (p->free && p->next->free) { + struct mem_block *q = p->next; + + assert(p->ofs + p->size == q->ofs); + p->size += q->size; + + p->next = q->next; + q->next->prev = p; + + q->next_free->prev_free = q->prev_free; + q->prev_free->next_free = q->next_free; + + FREE(q); + return 1; + } + return 0; +} + +int +mmFreeMem(struct mem_block *b) +{ + if (!b) + return 0; + + if (b->free) { + debug_printf("block already free\n"); + return -1; + } + if (b->reserved) { + debug_printf("block is reserved\n"); + return -1; + } + + b->free = 1; + b->next_free = b->heap->next_free; + b->prev_free = b->heap; + b->next_free->prev_free = b; + b->prev_free->next_free = b; + + Join2Blocks(b); + if (b->prev != b->heap) + Join2Blocks(b->prev); + + return 0; +} + + +void +mmDestroy(struct mem_block *heap) +{ + struct mem_block *p; + + if (!heap) + return; + + for (p = heap->next; p != heap; ) { + struct mem_block *next = p->next; + FREE(p); + p = next; + } + + FREE(heap); +} diff --git a/src/gallium/auxiliary/rtasm/mm.h b/src/gallium/auxiliary/rtasm/mm.h new file mode 100644 index 0000000000..f469b18d3e --- /dev/null +++ b/src/gallium/auxiliary/rtasm/mm.h @@ -0,0 +1,89 @@ +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * 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 + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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. + */ + + +/** + * Memory manager code. Primarily used by device drivers to manage texture + * heaps, etc. + */ + + +#ifndef MM_H +#define MM_H + + +struct mem_block { + struct mem_block *next, *prev; + struct mem_block *next_free, *prev_free; + struct mem_block *heap; + int ofs,size; + unsigned int free:1; + unsigned int reserved:1; +}; + + + +/** + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +extern struct mem_block *mmInit(int ofs, int size); + +/** + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +extern struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2, + int startSearch); + +/** + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +extern int mmFreeMem(struct mem_block *b); + +/** + * Free block starts at offset + * input: pointer to a heap, start offset + * return: pointer to a block + */ +extern struct mem_block *mmFindBlock(struct mem_block *heap, int start); + +/** + * destroy MM + */ +extern void mmDestroy(struct mem_block *mmInit); + +/** + * For debuging purpose. + */ +extern void mmDumpMemInfo(const struct mem_block *mmInit); + +#endif diff --git a/src/gallium/auxiliary/rtasm/x86sse.c b/src/gallium/auxiliary/rtasm/x86sse.c new file mode 100644 index 0000000000..fff6f77a6b --- /dev/null +++ b/src/gallium/auxiliary/rtasm/x86sse.c @@ -0,0 +1,1195 @@ +#if defined(__i386__) || defined(__386__) + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" + +#include "x86sse.h" + +#define DISASSEM 0 +#define X86_TWOB 0x0f + +static unsigned char *cptr( void (*label)() ) +{ + return (unsigned char *)(unsigned long)label; +} + + +static void do_realloc( struct x86_function *p ) +{ + if (p->size == 0) { + p->size = 1024; + p->store = _mesa_exec_malloc(p->size); + p->csr = p->store; + } + else { + unsigned used = p->csr - p->store; + unsigned char *tmp = p->store; + p->size *= 2; + p->store = _mesa_exec_malloc(p->size); + memcpy(p->store, tmp, used); + p->csr = p->store + used; + _mesa_exec_free(tmp); + } +} + +/* Emit bytes to the instruction stream: + */ +static unsigned char *reserve( struct x86_function *p, int bytes ) +{ + if (p->csr + bytes - p->store > p->size) + do_realloc(p); + + { + unsigned char *csr = p->csr; + p->csr += bytes; + return csr; + } +} + + + +static void emit_1b( struct x86_function *p, char b0 ) +{ + char *csr = (char *)reserve(p, 1); + *csr = b0; +} + +static void emit_1i( struct x86_function *p, int i0 ) +{ + int *icsr = (int *)reserve(p, sizeof(i0)); + *icsr = i0; +} + +static void emit_1ub( struct x86_function *p, unsigned char b0 ) +{ + unsigned char *csr = reserve(p, 1); + *csr++ = b0; +} + +static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) +{ + unsigned char *csr = reserve(p, 2); + *csr++ = b0; + *csr++ = b1; +} + +static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) +{ + unsigned char *csr = reserve(p, 3); + *csr++ = b0; + *csr++ = b1; + *csr++ = b2; +} + + +/* Build a modRM byte + possible displacement. No treatment of SIB + * indexing. BZZT - no way to encode an absolute address. + */ +static void emit_modrm( struct x86_function *p, + struct x86_reg reg, + struct x86_reg regmem ) +{ + unsigned char val = 0; + + assert(reg.mod == mod_REG); + + val |= regmem.mod << 6; /* mod field */ + val |= reg.idx << 3; /* reg field */ + val |= regmem.idx; /* r/m field */ + + emit_1ub(p, val); + + /* Oh-oh we've stumbled into the SIB thing. + */ + if (regmem.file == file_REG32 && + regmem.idx == reg_SP) { + emit_1ub(p, 0x24); /* simplistic! */ + } + + switch (regmem.mod) { + case mod_REG: + case mod_INDIRECT: + break; + case mod_DISP8: + emit_1b(p, regmem.disp); + break; + case mod_DISP32: + emit_1i(p, regmem.disp); + break; + default: + assert(0); + break; + } +} + + +static void emit_modrm_noreg( struct x86_function *p, + unsigned op, + struct x86_reg regmem ) +{ + struct x86_reg dummy = x86_make_reg(file_REG32, op); + emit_modrm(p, dummy, regmem); +} + +/* Many x86 instructions have two opcodes to cope with the situations + * where the destination is a register or memory reference + * respectively. This function selects the correct opcode based on + * the arguments presented. + */ +static void emit_op_modrm( struct x86_function *p, + unsigned char op_dst_is_reg, + unsigned char op_dst_is_mem, + struct x86_reg dst, + struct x86_reg src ) +{ + switch (dst.mod) { + case mod_REG: + emit_1ub(p, op_dst_is_reg); + emit_modrm(p, dst, src); + break; + case mod_INDIRECT: + case mod_DISP32: + case mod_DISP8: + assert(src.mod == mod_REG); + emit_1ub(p, op_dst_is_mem); + emit_modrm(p, src, dst); + break; + default: + assert(0); + break; + } +} + + + + + + + +/* Create and manipulate registers and regmem values: + */ +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ) +{ + struct x86_reg reg; + + reg.file = file; + reg.idx = idx; + reg.mod = mod_REG; + reg.disp = 0; + + return reg; +} + +struct x86_reg x86_make_disp( struct x86_reg reg, + int disp ) +{ + assert(reg.file == file_REG32); + + if (reg.mod == mod_REG) + reg.disp = disp; + else + reg.disp += disp; + + if (reg.disp == 0) + reg.mod = mod_INDIRECT; + else if (reg.disp <= 127 && reg.disp >= -128) + reg.mod = mod_DISP8; + else + reg.mod = mod_DISP32; + + return reg; +} + +struct x86_reg x86_deref( struct x86_reg reg ) +{ + return x86_make_disp(reg, 0); +} + +struct x86_reg x86_get_base_reg( struct x86_reg reg ) +{ + return x86_make_reg( reg.file, reg.idx ); +} + +unsigned char *x86_get_label( struct x86_function *p ) +{ + return p->csr; +} + + + +/*********************************************************************** + * x86 instructions + */ + + +void x86_jcc( struct x86_function *p, + enum x86_cc cc, + unsigned char *label ) +{ + int offset = label - (x86_get_label(p) + 2); + + if (offset <= 127 && offset >= -128) { + emit_1ub(p, 0x70 + cc); + emit_1b(p, (char) offset); + } + else { + offset = label - (x86_get_label(p) + 6); + emit_2ub(p, 0x0f, 0x80 + cc); + emit_1i(p, offset); + } +} + +/* Always use a 32bit offset for forward jumps: + */ +unsigned char *x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ) +{ + emit_2ub(p, 0x0f, 0x80 + cc); + emit_1i(p, 0); + return x86_get_label(p); +} + +unsigned char *x86_jmp_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe9); + emit_1i(p, 0); + return x86_get_label(p); +} + +unsigned char *x86_call_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe8); + emit_1i(p, 0); + return x86_get_label(p); +} + +/* Fixup offset from forward jump: + */ +void x86_fixup_fwd_jump( struct x86_function *p, + unsigned char *fixup ) +{ + *(int *)(fixup - 4) = x86_get_label(p) - fixup; +} + +void x86_jmp( struct x86_function *p, unsigned char *label) +{ + emit_1ub(p, 0xe9); + emit_1i(p, label - x86_get_label(p) - 4); +} + +#if 0 +/* This doesn't work once we start reallocating & copying the + * generated code on buffer fills, because the call is relative to the + * current pc. + */ +void x86_call( struct x86_function *p, void (*label)()) +{ + emit_1ub(p, 0xe8); + emit_1i(p, cptr(label) - x86_get_label(p) - 4); +} +#else +void x86_call( struct x86_function *p, struct x86_reg reg) +{ + emit_1ub(p, 0xff); + emit_modrm(p, reg, reg); +} +#endif + + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) +{ + assert(dst.mod == mod_REG); + emit_1ub(p, 0xb8 + dst.idx); + emit_1i(p, imm); +} + +void x86_push( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x50 + reg.idx); + p->stack_offset += 4; +} + +void x86_pop( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x58 + reg.idx); + p->stack_offset -= 4; +} + +void x86_inc( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x40 + reg.idx); +} + +void x86_dec( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x48 + reg.idx); +} + +void x86_ret( struct x86_function *p ) +{ + emit_1ub(p, 0xc3); +} + +void x86_sahf( struct x86_function *p ) +{ + emit_1ub(p, 0x9e); +} + +void x86_mov( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x8b, 0x89, dst, src ); +} + +void x86_xor( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x33, 0x31, dst, src ); +} + +void x86_cmp( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x3b, 0x39, dst, src ); +} + +void x86_lea( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, 0x8d); + emit_modrm( p, dst, src ); +} + +void x86_test( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, 0x85); + emit_modrm( p, dst, src ); +} + +void x86_add( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x03, 0x01, dst, src ); +} + +void x86_mul( struct x86_function *p, + struct x86_reg src ) +{ + assert (src.file == file_REG32 && src.mod == mod_REG); + emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); +} + +void x86_sub( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x2b, 0x29, dst, src ); +} + +void x86_or( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x0b, 0x09, dst, src ); +} + +void x86_and( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x23, 0x21, dst, src ); +} + + + +/*********************************************************************** + * SSE instructions + */ + + +void sse_movss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, 0xF3, X86_TWOB); + emit_op_modrm( p, 0x10, 0x11, dst, src ); +} + +void sse_movaps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x28, 0x29, dst, src ); +} + +void sse_movups( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x10, 0x11, dst, src ); +} + +void sse_movhps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod != mod_REG || src.mod != mod_REG); + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ +} + +void sse_movlps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod != mod_REG || src.mod != mod_REG); + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ +} + +void sse_maxps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5F); + emit_modrm( p, dst, src ); +} + +void sse_maxss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x5F); + emit_modrm( p, dst, src ); +} + +void sse_divss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x5E); + emit_modrm( p, dst, src ); +} + +void sse_minps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5D); + emit_modrm( p, dst, src ); +} + +void sse_subps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5C); + emit_modrm( p, dst, src ); +} + +void sse_mulps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x59); + emit_modrm( p, dst, src ); +} + +void sse_mulss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x59); + emit_modrm( p, dst, src ); +} + +void sse_addps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x58); + emit_modrm( p, dst, src ); +} + +void sse_addss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x58); + emit_modrm( p, dst, src ); +} + +void sse_andnps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x55); + emit_modrm( p, dst, src ); +} + +void sse_andps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x54); + emit_modrm( p, dst, src ); +} + +void sse_rsqrtps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x52); + emit_modrm( p, dst, src ); +} + +void sse_rsqrtss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x52); + emit_modrm( p, dst, src ); + +} + +void sse_movhlps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod == mod_REG && src.mod == mod_REG); + emit_2ub(p, X86_TWOB, 0x12); + emit_modrm( p, dst, src ); +} + +void sse_movlhps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod == mod_REG && src.mod == mod_REG); + emit_2ub(p, X86_TWOB, 0x16); + emit_modrm( p, dst, src ); +} + +void sse_orps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x56); + emit_modrm( p, dst, src ); +} + +void sse_xorps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x57); + emit_modrm( p, dst, src ); +} + +void sse_cvtps2pi( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_XMM || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x2d); + emit_modrm( p, dst, src ); +} + + +/* Shufps can also be used to implement a reduced swizzle when dest == + * arg0. + */ +void sse_shufps( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char shuf) +{ + emit_2ub(p, X86_TWOB, 0xC6); + emit_modrm(p, dest, arg0); + emit_1ub(p, shuf); +} + +void sse_cmpps( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char cc) +{ + emit_2ub(p, X86_TWOB, 0xC2); + emit_modrm(p, dest, arg0); + emit_1ub(p, cc); +} + +void sse_pmovmskb( struct x86_function *p, + struct x86_reg dest, + struct x86_reg src) +{ + emit_3ub(p, 0x66, X86_TWOB, 0xD7); + emit_modrm(p, dest, src); +} + +/*********************************************************************** + * SSE2 instructions + */ + +/** + * Perform a reduced swizzle: + */ +void sse2_pshufd( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char shuf) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x70); + emit_modrm(p, dest, arg0); + emit_1ub(p, shuf); +} + +void sse2_cvttps2dq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); + emit_modrm( p, dst, src ); +} + +void sse2_cvtps2dq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x5B); + emit_modrm( p, dst, src ); +} + +void sse2_packssdw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x6B); + emit_modrm( p, dst, src ); +} + +void sse2_packsswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x63); + emit_modrm( p, dst, src ); +} + +void sse2_packuswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x67); + emit_modrm( p, dst, src ); +} + +void sse2_rcpps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x53); + emit_modrm( p, dst, src ); +} + +void sse2_rcpss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x53); + emit_modrm( p, dst, src ); +} + +void sse2_movd( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, 0x66, X86_TWOB); + emit_op_modrm( p, 0x6e, 0x7e, dst, src ); +} + + + + +/*********************************************************************** + * x87 instructions + */ +void x87_fist( struct x86_function *p, struct x86_reg dst ) +{ + emit_1ub(p, 0xdb); + emit_modrm_noreg(p, 2, dst); +} + +void x87_fistp( struct x86_function *p, struct x86_reg dst ) +{ + emit_1ub(p, 0xdb); + emit_modrm_noreg(p, 3, dst); +} + +void x87_fild( struct x86_function *p, struct x86_reg arg ) +{ + emit_1ub(p, 0xdf); + emit_modrm_noreg(p, 0, arg); +} + +void x87_fldz( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xee); +} + + +void x87_fldcw( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_REG32); + assert(arg.mod != mod_REG); + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 5, arg); +} + +void x87_fld1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe8); +} + +void x87_fldl2e( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xea); +} + +void x87_fldln2( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xed); +} + +void x87_fwait( struct x86_function *p ) +{ + emit_1ub(p, 0x9b); +} + +void x87_fnclex( struct x86_function *p ) +{ + emit_2ub(p, 0xdb, 0xe2); +} + +void x87_fclex( struct x86_function *p ) +{ + x87_fwait(p); + x87_fnclex(p); +} + + +static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, + unsigned char dst0ub0, + unsigned char dst0ub1, + unsigned char arg0ub0, + unsigned char arg0ub1, + unsigned char argmem_noreg) +{ + assert(dst.file == file_x87); + + if (arg.file == file_x87) { + if (dst.idx == 0) + emit_2ub(p, dst0ub0, dst0ub1+arg.idx); + else if (arg.idx == 0) + emit_2ub(p, arg0ub0, arg0ub1+arg.idx); + else + assert(0); + } + else if (dst.idx == 0) { + assert(arg.file == file_REG32); + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, argmem_noreg, arg); + } + else + assert(0); +} + +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xc8, + 0xdc, 0xc8, + 4); +} + +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xe0, + 0xdc, 0xe8, + 4); +} + +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xe8, + 0xdc, 0xe0, + 5); +} + +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xc0, + 0xdc, 0xc0, + 0); +} + +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xf0, + 0xdc, 0xf8, + 6); +} + +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xf8, + 0xdc, 0xf0, + 7); +} + +void x87_fmulp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xc8+dst.idx); +} + +void x87_fsubp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xe8+dst.idx); +} + +void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xe0+dst.idx); +} + +void x87_faddp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xc0+dst.idx); +} + +void x87_fdivp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xf8+dst.idx); +} + +void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xf0+dst.idx); +} + +void x87_fucom( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xdd, 0xe0+arg.idx); +} + +void x87_fucomp( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xdd, 0xe8+arg.idx); +} + +void x87_fucompp( struct x86_function *p ) +{ + emit_2ub(p, 0xda, 0xe9); +} + +void x87_fxch( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xd9, 0xc8+arg.idx); +} + +void x87_fabs( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe1); +} + +void x87_fchs( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe0); +} + +void x87_fcos( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xff); +} + + +void x87_fprndint( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfc); +} + +void x87_fscale( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfd); +} + +void x87_fsin( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfe); +} + +void x87_fsincos( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfb); +} + +void x87_fsqrt( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfa); +} + +void x87_fxtract( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf4); +} + +/* st0 = (2^st0)-1 + * + * Restrictions: -1.0 <= st0 <= 1.0 + */ +void x87_f2xm1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf0); +} + +/* st1 = st1 * log2(st0); + * pop_stack; + */ +void x87_fyl2x( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf1); +} + +/* st1 = st1 * log2(st0 + 1.0); + * pop_stack; + * + * A fast operation, with restrictions: -.29 < st0 < .29 + */ +void x87_fyl2xp1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf9); +} + + +void x87_fld( struct x86_function *p, struct x86_reg arg ) +{ + if (arg.file == file_x87) + emit_2ub(p, 0xd9, 0xc0 + arg.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 0, arg); + } +} + +void x87_fst( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xdd, 0xd0 + dst.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 2, dst); + } +} + +void x87_fstp( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xdd, 0xd8 + dst.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 3, dst); + } +} + +void x87_fcom( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xd8, 0xd0 + dst.idx); + else { + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, 2, dst); + } +} + +void x87_fcomp( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xd8, 0xd8 + dst.idx); + else { + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, 3, dst); + } +} + + +void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_REG32); + + if (dst.idx == reg_AX && + dst.mod == mod_REG) + emit_2ub(p, 0xdf, 0xe0); + else { + emit_1ub(p, 0xdd); + emit_modrm_noreg(p, 7, dst); + } +} + + + + +/*********************************************************************** + * MMX instructions + */ + +void mmx_emms( struct x86_function *p ) +{ + assert(p->need_emms); + emit_2ub(p, 0x0f, 0x77); + p->need_emms = 0; +} + +void mmx_packssdw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_MMX || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x6b); + emit_modrm( p, dst, src ); +} + +void mmx_packuswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_MMX || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x67); + emit_modrm( p, dst, src ); +} + +void mmx_movd( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + p->need_emms = 1; + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x6e, 0x7e, dst, src ); +} + +void mmx_movq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + p->need_emms = 1; + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x6f, 0x7f, dst, src ); +} + + +/*********************************************************************** + * Helper functions + */ + + +/* Retreive a reference to one of the function arguments, taking into + * account any push/pop activity: + */ +struct x86_reg x86_fn_arg( struct x86_function *p, + unsigned arg ) +{ + return x86_make_disp(x86_make_reg(file_REG32, reg_SP), + p->stack_offset + arg * 4); /* ??? */ +} + + +void x86_init_func( struct x86_function *p ) +{ + p->size = 0; + p->store = NULL; + p->csr = p->store; +} + +void x86_init_func_size( struct x86_function *p, unsigned code_size ) +{ + p->size = code_size; + p->store = _mesa_exec_malloc(code_size); + p->csr = p->store; +} + +void x86_release_func( struct x86_function *p ) +{ + _mesa_exec_free(p->store); + p->store = NULL; + p->csr = NULL; + p->size = 0; +} + + +void (*x86_get_func( struct x86_function *p ))(void) +{ + if (DISASSEM && p->store) + _mesa_printf("disassemble %p %p\n", p->store, p->csr); + return (void (*)(void)) (unsigned long) p->store; +} + +#else + +void x86sse_dummy( void ) +{ +} + +#endif diff --git a/src/gallium/auxiliary/rtasm/x86sse.h b/src/gallium/auxiliary/rtasm/x86sse.h new file mode 100644 index 0000000000..c2aa416492 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/x86sse.h @@ -0,0 +1,256 @@ + +#ifndef _X86SSE_H_ +#define _X86SSE_H_ + +#if defined(__i386__) || defined(__386__) + +/* It is up to the caller to ensure that instructions issued are + * suitable for the host cpu. There are no checks made in this module + * for mmx/sse/sse2 support on the cpu. + */ +struct x86_reg { + unsigned file:3; + unsigned idx:3; + unsigned mod:2; /* mod_REG if this is just a register */ + int disp:24; /* only +/- 23bits of offset - should be enough... */ +}; + +struct x86_function { + unsigned size; + unsigned char *store; + unsigned char *csr; + unsigned stack_offset; + int need_emms; + const char *fn; +}; + +enum x86_reg_file { + file_REG32, + file_MMX, + file_XMM, + file_x87 +}; + +/* Values for mod field of modr/m byte + */ +enum x86_reg_mod { + mod_INDIRECT, + mod_DISP8, + mod_DISP32, + mod_REG +}; + +enum x86_reg_name { + reg_AX, + reg_CX, + reg_DX, + reg_BX, + reg_SP, + reg_BP, + reg_SI, + reg_DI +}; + + +enum x86_cc { + cc_O, /* overflow */ + cc_NO, /* not overflow */ + cc_NAE, /* not above or equal / carry */ + cc_AE, /* above or equal / not carry */ + cc_E, /* equal / zero */ + cc_NE /* not equal / not zero */ +}; + +enum sse_cc { + cc_Equal, + cc_LessThan, + cc_LessThanEqual, + cc_Unordered, + cc_NotEqual, + cc_NotLessThan, + cc_NotLessThanEqual, + cc_Ordered +}; + +#define cc_Z cc_E +#define cc_NZ cc_NE + +/* Begin/end/retreive function creation: + */ + + +void x86_init_func( struct x86_function *p ); +void x86_init_func_size( struct x86_function *p, unsigned code_size ); +void x86_release_func( struct x86_function *p ); +void (*x86_get_func( struct x86_function *p ))( void ); + + + +/* Create and manipulate registers and regmem values: + */ +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ); + +struct x86_reg x86_make_disp( struct x86_reg reg, + int disp ); + +struct x86_reg x86_deref( struct x86_reg reg ); + +struct x86_reg x86_get_base_reg( struct x86_reg reg ); + + +/* Labels, jumps and fixup: + */ +unsigned char *x86_get_label( struct x86_function *p ); + +void x86_jcc( struct x86_function *p, + enum x86_cc cc, + unsigned char *label ); + +unsigned char *x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ); + +unsigned char *x86_jmp_forward( struct x86_function *p); + +unsigned char *x86_call_forward( struct x86_function *p); + +void x86_fixup_fwd_jump( struct x86_function *p, + unsigned char *fixup ); + +void x86_jmp( struct x86_function *p, unsigned char *label ); + +/* void x86_call( struct x86_function *p, void (*label)() ); */ +void x86_call( struct x86_function *p, struct x86_reg reg); + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); + + +/* Macro for sse_shufps() and sse2_pshufd(): + */ +#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6)) +#define SHUF_NOOP RSW(0,1,2,3) +#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3) + +void mmx_emms( struct x86_function *p ); +void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); + +void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, + unsigned char shuf ); +void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); + +void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, + unsigned char cc ); +void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, + unsigned char shuf ); +void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); + +void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_dec( struct x86_function *p, struct x86_reg reg ); +void x86_inc( struct x86_function *p, struct x86_reg reg ); +void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mul( struct x86_function *p, struct x86_reg src ); +void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_pop( struct x86_function *p, struct x86_reg reg ); +void x86_push( struct x86_function *p, struct x86_reg reg ); +void x86_ret( struct x86_function *p ); +void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_sahf( struct x86_function *p ); + +void x87_f2xm1( struct x86_function *p ); +void x87_fabs( struct x86_function *p ); +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_faddp( struct x86_function *p, struct x86_reg dst ); +void x87_fchs( struct x86_function *p ); +void x87_fclex( struct x86_function *p ); +void x87_fcom( struct x86_function *p, struct x86_reg dst ); +void x87_fcomp( struct x86_function *p, struct x86_reg dst ); +void x87_fcos( struct x86_function *p ); +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fdivp( struct x86_function *p, struct x86_reg dst ); +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fdivrp( struct x86_function *p, struct x86_reg dst ); +void x87_fild( struct x86_function *p, struct x86_reg arg ); +void x87_fist( struct x86_function *p, struct x86_reg dst ); +void x87_fistp( struct x86_function *p, struct x86_reg dst ); +void x87_fld( struct x86_function *p, struct x86_reg arg ); +void x87_fld1( struct x86_function *p ); +void x87_fldcw( struct x86_function *p, struct x86_reg arg ); +void x87_fldl2e( struct x86_function *p ); +void x87_fldln2( struct x86_function *p ); +void x87_fldz( struct x86_function *p ); +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fmulp( struct x86_function *p, struct x86_reg dst ); +void x87_fnclex( struct x86_function *p ); +void x87_fprndint( struct x86_function *p ); +void x87_fscale( struct x86_function *p ); +void x87_fsin( struct x86_function *p ); +void x87_fsincos( struct x86_function *p ); +void x87_fsqrt( struct x86_function *p ); +void x87_fst( struct x86_function *p, struct x86_reg dst ); +void x87_fstp( struct x86_function *p, struct x86_reg dst ); +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fsubp( struct x86_function *p, struct x86_reg dst ); +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); +void x87_fxch( struct x86_function *p, struct x86_reg dst ); +void x87_fxtract( struct x86_function *p ); +void x87_fyl2x( struct x86_function *p ); +void x87_fyl2xp1( struct x86_function *p ); +void x87_fwait( struct x86_function *p ); +void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); +void x87_fucompp( struct x86_function *p ); +void x87_fucomp( struct x86_function *p, struct x86_reg arg ); +void x87_fucom( struct x86_function *p, struct x86_reg arg ); + + + +/* Retreive a reference to one of the function arguments, taking into + * account any push/pop activity. Note - doesn't track explict + * manipulation of ESP by other instructions. + */ +struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); + +#endif +#endif -- cgit v1.2.3 From 39ea0308425ad04618061129c63c22ac0efb0692 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 12:00:48 +0900 Subject: Rename rtasm files. --- src/gallium/auxiliary/rtasm/Makefile | 4 +- src/gallium/auxiliary/rtasm/SConscript | 4 +- src/gallium/auxiliary/rtasm/execmem.c | 133 --- src/gallium/auxiliary/rtasm/execmem.h | 45 - src/gallium/auxiliary/rtasm/rtasm_execmem.c | 134 +++ src/gallium/auxiliary/rtasm/rtasm_execmem.h | 45 + src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 1196 +++++++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 256 ++++++ src/gallium/auxiliary/rtasm/x86sse.c | 1195 -------------------------- src/gallium/auxiliary/rtasm/x86sse.h | 256 ------ 10 files changed, 1635 insertions(+), 1633 deletions(-) delete mode 100644 src/gallium/auxiliary/rtasm/execmem.c delete mode 100644 src/gallium/auxiliary/rtasm/execmem.h create mode 100644 src/gallium/auxiliary/rtasm/rtasm_execmem.c create mode 100644 src/gallium/auxiliary/rtasm/rtasm_execmem.h create mode 100644 src/gallium/auxiliary/rtasm/rtasm_x86sse.c create mode 100644 src/gallium/auxiliary/rtasm/rtasm_x86sse.h delete mode 100644 src/gallium/auxiliary/rtasm/x86sse.c delete mode 100644 src/gallium/auxiliary/rtasm/x86sse.h (limited to 'src') diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index b3b9934e10..7c8ac60794 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -5,9 +5,9 @@ include $(TOP)/configs/current LIBNAME = rtasm DRIVER_SOURCES = \ + execmem.c \ x86sse.c \ - mm.c \ - execmem.c + mm.c C_SOURCES = \ $(DRIVER_SOURCES) diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index c5b1551786..de8456e0ca 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -3,9 +3,9 @@ Import('*') rtasm = env.ConvenienceLibrary( target = 'rtasm', source = [ - 'x86sse.c', + 'rtasm_execmem.c', + 'rtasm_x86sse.c', 'mm.c', - 'execmem.c', ]) auxiliaries.insert(0, rtasm) diff --git a/src/gallium/auxiliary/rtasm/execmem.c b/src/gallium/auxiliary/rtasm/execmem.c deleted file mode 100644 index c7c35f7ef2..0000000000 --- a/src/gallium/auxiliary/rtasm/execmem.c +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * \file exemem.c - * Functions for allocating executable memory. - * - * \author Keith Whitwell - */ - - -#include "pipe/p_compiler.h" -#include "pipe/p_thread.h" - -#include "execmem.h" - - -#if defined(__linux__) - -/* - * Allocate a large block of memory which can hold code then dole it out - * in pieces by means of the generic memory manager code. -*/ - -#include -#include -#include "mm.h" - -#define EXEC_HEAP_SIZE (10*1024*1024) - -_glthread_DECLARE_STATIC_MUTEX(exec_mutex); - -static struct mem_block *exec_heap = NULL; -static unsigned char *exec_mem = NULL; - - -static void -init_heap(void) -{ - if (!exec_heap) - exec_heap = mmInit( 0, EXEC_HEAP_SIZE ); - - if (!exec_mem) - exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -} - - -void * -_mesa_exec_malloc(size_t size) -{ - struct mem_block *block = NULL; - void *addr = NULL; - - _glthread_LOCK_MUTEX(exec_mutex); - - init_heap(); - - if (exec_heap) { - size = (size + 31) & ~31; - block = mmAllocMem( exec_heap, size, 32, 0 ); - } - - if (block) - addr = exec_mem + block->ofs; - else - debug_printf("_mesa_exec_malloc failed\n"); - - _glthread_UNLOCK_MUTEX(exec_mutex); - - return addr; -} - - -void -_mesa_exec_free(void *addr) -{ - _glthread_LOCK_MUTEX(exec_mutex); - - if (exec_heap) { - struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); - - if (block) - mmFreeMem(block); - } - - _glthread_UNLOCK_MUTEX(exec_mutex); -} - - -#else - -/* - * Just use regular memory. - */ - -void * -_mesa_exec_malloc(GLuint size) -{ - return _mesa_malloc( size ); -} - - -void -_mesa_exec_free(void *addr) -{ - _mesa_free(addr); -} - - -#endif diff --git a/src/gallium/auxiliary/rtasm/execmem.h b/src/gallium/auxiliary/rtasm/execmem.h deleted file mode 100644 index 9fd4569165..0000000000 --- a/src/gallium/auxiliary/rtasm/execmem.h +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * \file exemem.c - * Functions for allocating executable memory. - * - * \author Keith Whitwell - */ - -#ifndef _EXECMEM_H_ -#define _EXECMEM_H_ - -#include "pipe/p_compiler.h" - - -extern void * -_mesa_exec_malloc( size_t size ); - - -extern void -_mesa_exec_free( void *addr ); - - -#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c new file mode 100644 index 0000000000..cb13db2498 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -0,0 +1,134 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * \file exemem.c + * Functions for allocating executable memory. + * + * \author Keith Whitwell + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" + +#include "rtasm_execmem.h" + + +#if defined(__linux__) + +/* + * Allocate a large block of memory which can hold code then dole it out + * in pieces by means of the generic memory manager code. +*/ + +#include +#include +#include "mm.h" + +#define EXEC_HEAP_SIZE (10*1024*1024) + +_glthread_DECLARE_STATIC_MUTEX(exec_mutex); + +static struct mem_block *exec_heap = NULL; +static unsigned char *exec_mem = NULL; + + +static void +init_heap(void) +{ + if (!exec_heap) + exec_heap = mmInit( 0, EXEC_HEAP_SIZE ); + + if (!exec_mem) + exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +} + + +void * +rtasm_exec_malloc(size_t size) +{ + struct mem_block *block = NULL; + void *addr = NULL; + + _glthread_LOCK_MUTEX(exec_mutex); + + init_heap(); + + if (exec_heap) { + size = (size + 31) & ~31; + block = mmAllocMem( exec_heap, size, 32, 0 ); + } + + if (block) + addr = exec_mem + block->ofs; + else + debug_printf("rtasm_exec_malloc failed\n"); + + _glthread_UNLOCK_MUTEX(exec_mutex); + + return addr; +} + + +void +rtasm_exec_free(void *addr) +{ + _glthread_LOCK_MUTEX(exec_mutex); + + if (exec_heap) { + struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); + + if (block) + mmFreeMem(block); + } + + _glthread_UNLOCK_MUTEX(exec_mutex); +} + + +#else + +/* + * Just use regular memory. + */ + +void * +rtasm_exec_malloc(GLuint size) +{ + return MALLOC( size ); +} + + +void +rtasm_exec_free(void *addr) +{ + FREE(addr); +} + + +#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.h b/src/gallium/auxiliary/rtasm/rtasm_execmem.h new file mode 100644 index 0000000000..155c6d34e0 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.h @@ -0,0 +1,45 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file exemem.c + * Functions for allocating executable memory. + * + * \author Keith Whitwell + */ + +#ifndef _RTASM_EXECMEM_H_ +#define _RTASM_EXECMEM_H_ + +#include "pipe/p_compiler.h" + + +extern void * +rtasm_exec_malloc( size_t size ); + + +extern void +rtasm_exec_free( void *addr ); + + +#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c new file mode 100644 index 0000000000..3c885a9fff --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -0,0 +1,1196 @@ +#if defined(__i386__) || defined(__386__) + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" + +#include "rtasm_execmem.h" +#include "rtasm_x86sse.h" + +#define DISASSEM 0 +#define X86_TWOB 0x0f + +static unsigned char *cptr( void (*label)() ) +{ + return (unsigned char *)(unsigned long)label; +} + + +static void do_realloc( struct x86_function *p ) +{ + if (p->size == 0) { + p->size = 1024; + p->store = rtasm_exec_malloc(p->size); + p->csr = p->store; + } + else { + unsigned used = p->csr - p->store; + unsigned char *tmp = p->store; + p->size *= 2; + p->store = rtasm_exec_malloc(p->size); + memcpy(p->store, tmp, used); + p->csr = p->store + used; + rtasm_exec_free(tmp); + } +} + +/* Emit bytes to the instruction stream: + */ +static unsigned char *reserve( struct x86_function *p, int bytes ) +{ + if (p->csr + bytes - p->store > p->size) + do_realloc(p); + + { + unsigned char *csr = p->csr; + p->csr += bytes; + return csr; + } +} + + + +static void emit_1b( struct x86_function *p, char b0 ) +{ + char *csr = (char *)reserve(p, 1); + *csr = b0; +} + +static void emit_1i( struct x86_function *p, int i0 ) +{ + int *icsr = (int *)reserve(p, sizeof(i0)); + *icsr = i0; +} + +static void emit_1ub( struct x86_function *p, unsigned char b0 ) +{ + unsigned char *csr = reserve(p, 1); + *csr++ = b0; +} + +static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) +{ + unsigned char *csr = reserve(p, 2); + *csr++ = b0; + *csr++ = b1; +} + +static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) +{ + unsigned char *csr = reserve(p, 3); + *csr++ = b0; + *csr++ = b1; + *csr++ = b2; +} + + +/* Build a modRM byte + possible displacement. No treatment of SIB + * indexing. BZZT - no way to encode an absolute address. + */ +static void emit_modrm( struct x86_function *p, + struct x86_reg reg, + struct x86_reg regmem ) +{ + unsigned char val = 0; + + assert(reg.mod == mod_REG); + + val |= regmem.mod << 6; /* mod field */ + val |= reg.idx << 3; /* reg field */ + val |= regmem.idx; /* r/m field */ + + emit_1ub(p, val); + + /* Oh-oh we've stumbled into the SIB thing. + */ + if (regmem.file == file_REG32 && + regmem.idx == reg_SP) { + emit_1ub(p, 0x24); /* simplistic! */ + } + + switch (regmem.mod) { + case mod_REG: + case mod_INDIRECT: + break; + case mod_DISP8: + emit_1b(p, regmem.disp); + break; + case mod_DISP32: + emit_1i(p, regmem.disp); + break; + default: + assert(0); + break; + } +} + + +static void emit_modrm_noreg( struct x86_function *p, + unsigned op, + struct x86_reg regmem ) +{ + struct x86_reg dummy = x86_make_reg(file_REG32, op); + emit_modrm(p, dummy, regmem); +} + +/* Many x86 instructions have two opcodes to cope with the situations + * where the destination is a register or memory reference + * respectively. This function selects the correct opcode based on + * the arguments presented. + */ +static void emit_op_modrm( struct x86_function *p, + unsigned char op_dst_is_reg, + unsigned char op_dst_is_mem, + struct x86_reg dst, + struct x86_reg src ) +{ + switch (dst.mod) { + case mod_REG: + emit_1ub(p, op_dst_is_reg); + emit_modrm(p, dst, src); + break; + case mod_INDIRECT: + case mod_DISP32: + case mod_DISP8: + assert(src.mod == mod_REG); + emit_1ub(p, op_dst_is_mem); + emit_modrm(p, src, dst); + break; + default: + assert(0); + break; + } +} + + + + + + + +/* Create and manipulate registers and regmem values: + */ +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ) +{ + struct x86_reg reg; + + reg.file = file; + reg.idx = idx; + reg.mod = mod_REG; + reg.disp = 0; + + return reg; +} + +struct x86_reg x86_make_disp( struct x86_reg reg, + int disp ) +{ + assert(reg.file == file_REG32); + + if (reg.mod == mod_REG) + reg.disp = disp; + else + reg.disp += disp; + + if (reg.disp == 0) + reg.mod = mod_INDIRECT; + else if (reg.disp <= 127 && reg.disp >= -128) + reg.mod = mod_DISP8; + else + reg.mod = mod_DISP32; + + return reg; +} + +struct x86_reg x86_deref( struct x86_reg reg ) +{ + return x86_make_disp(reg, 0); +} + +struct x86_reg x86_get_base_reg( struct x86_reg reg ) +{ + return x86_make_reg( reg.file, reg.idx ); +} + +unsigned char *x86_get_label( struct x86_function *p ) +{ + return p->csr; +} + + + +/*********************************************************************** + * x86 instructions + */ + + +void x86_jcc( struct x86_function *p, + enum x86_cc cc, + unsigned char *label ) +{ + int offset = label - (x86_get_label(p) + 2); + + if (offset <= 127 && offset >= -128) { + emit_1ub(p, 0x70 + cc); + emit_1b(p, (char) offset); + } + else { + offset = label - (x86_get_label(p) + 6); + emit_2ub(p, 0x0f, 0x80 + cc); + emit_1i(p, offset); + } +} + +/* Always use a 32bit offset for forward jumps: + */ +unsigned char *x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ) +{ + emit_2ub(p, 0x0f, 0x80 + cc); + emit_1i(p, 0); + return x86_get_label(p); +} + +unsigned char *x86_jmp_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe9); + emit_1i(p, 0); + return x86_get_label(p); +} + +unsigned char *x86_call_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe8); + emit_1i(p, 0); + return x86_get_label(p); +} + +/* Fixup offset from forward jump: + */ +void x86_fixup_fwd_jump( struct x86_function *p, + unsigned char *fixup ) +{ + *(int *)(fixup - 4) = x86_get_label(p) - fixup; +} + +void x86_jmp( struct x86_function *p, unsigned char *label) +{ + emit_1ub(p, 0xe9); + emit_1i(p, label - x86_get_label(p) - 4); +} + +#if 0 +/* This doesn't work once we start reallocating & copying the + * generated code on buffer fills, because the call is relative to the + * current pc. + */ +void x86_call( struct x86_function *p, void (*label)()) +{ + emit_1ub(p, 0xe8); + emit_1i(p, cptr(label) - x86_get_label(p) - 4); +} +#else +void x86_call( struct x86_function *p, struct x86_reg reg) +{ + emit_1ub(p, 0xff); + emit_modrm(p, reg, reg); +} +#endif + + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) +{ + assert(dst.mod == mod_REG); + emit_1ub(p, 0xb8 + dst.idx); + emit_1i(p, imm); +} + +void x86_push( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x50 + reg.idx); + p->stack_offset += 4; +} + +void x86_pop( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x58 + reg.idx); + p->stack_offset -= 4; +} + +void x86_inc( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x40 + reg.idx); +} + +void x86_dec( struct x86_function *p, + struct x86_reg reg ) +{ + assert(reg.mod == mod_REG); + emit_1ub(p, 0x48 + reg.idx); +} + +void x86_ret( struct x86_function *p ) +{ + emit_1ub(p, 0xc3); +} + +void x86_sahf( struct x86_function *p ) +{ + emit_1ub(p, 0x9e); +} + +void x86_mov( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x8b, 0x89, dst, src ); +} + +void x86_xor( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x33, 0x31, dst, src ); +} + +void x86_cmp( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x3b, 0x39, dst, src ); +} + +void x86_lea( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, 0x8d); + emit_modrm( p, dst, src ); +} + +void x86_test( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, 0x85); + emit_modrm( p, dst, src ); +} + +void x86_add( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x03, 0x01, dst, src ); +} + +void x86_mul( struct x86_function *p, + struct x86_reg src ) +{ + assert (src.file == file_REG32 && src.mod == mod_REG); + emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); +} + +void x86_sub( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x2b, 0x29, dst, src ); +} + +void x86_or( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x0b, 0x09, dst, src ); +} + +void x86_and( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm( p, 0x23, 0x21, dst, src ); +} + + + +/*********************************************************************** + * SSE instructions + */ + + +void sse_movss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, 0xF3, X86_TWOB); + emit_op_modrm( p, 0x10, 0x11, dst, src ); +} + +void sse_movaps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x28, 0x29, dst, src ); +} + +void sse_movups( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x10, 0x11, dst, src ); +} + +void sse_movhps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod != mod_REG || src.mod != mod_REG); + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ +} + +void sse_movlps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod != mod_REG || src.mod != mod_REG); + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ +} + +void sse_maxps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5F); + emit_modrm( p, dst, src ); +} + +void sse_maxss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x5F); + emit_modrm( p, dst, src ); +} + +void sse_divss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x5E); + emit_modrm( p, dst, src ); +} + +void sse_minps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5D); + emit_modrm( p, dst, src ); +} + +void sse_subps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5C); + emit_modrm( p, dst, src ); +} + +void sse_mulps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x59); + emit_modrm( p, dst, src ); +} + +void sse_mulss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x59); + emit_modrm( p, dst, src ); +} + +void sse_addps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x58); + emit_modrm( p, dst, src ); +} + +void sse_addss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x58); + emit_modrm( p, dst, src ); +} + +void sse_andnps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x55); + emit_modrm( p, dst, src ); +} + +void sse_andps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x54); + emit_modrm( p, dst, src ); +} + +void sse_rsqrtps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x52); + emit_modrm( p, dst, src ); +} + +void sse_rsqrtss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x52); + emit_modrm( p, dst, src ); + +} + +void sse_movhlps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod == mod_REG && src.mod == mod_REG); + emit_2ub(p, X86_TWOB, 0x12); + emit_modrm( p, dst, src ); +} + +void sse_movlhps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.mod == mod_REG && src.mod == mod_REG); + emit_2ub(p, X86_TWOB, 0x16); + emit_modrm( p, dst, src ); +} + +void sse_orps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x56); + emit_modrm( p, dst, src ); +} + +void sse_xorps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x57); + emit_modrm( p, dst, src ); +} + +void sse_cvtps2pi( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_XMM || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x2d); + emit_modrm( p, dst, src ); +} + + +/* Shufps can also be used to implement a reduced swizzle when dest == + * arg0. + */ +void sse_shufps( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char shuf) +{ + emit_2ub(p, X86_TWOB, 0xC6); + emit_modrm(p, dest, arg0); + emit_1ub(p, shuf); +} + +void sse_cmpps( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char cc) +{ + emit_2ub(p, X86_TWOB, 0xC2); + emit_modrm(p, dest, arg0); + emit_1ub(p, cc); +} + +void sse_pmovmskb( struct x86_function *p, + struct x86_reg dest, + struct x86_reg src) +{ + emit_3ub(p, 0x66, X86_TWOB, 0xD7); + emit_modrm(p, dest, src); +} + +/*********************************************************************** + * SSE2 instructions + */ + +/** + * Perform a reduced swizzle: + */ +void sse2_pshufd( struct x86_function *p, + struct x86_reg dest, + struct x86_reg arg0, + unsigned char shuf) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x70); + emit_modrm(p, dest, arg0); + emit_1ub(p, shuf); +} + +void sse2_cvttps2dq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); + emit_modrm( p, dst, src ); +} + +void sse2_cvtps2dq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x5B); + emit_modrm( p, dst, src ); +} + +void sse2_packssdw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x6B); + emit_modrm( p, dst, src ); +} + +void sse2_packsswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x63); + emit_modrm( p, dst, src ); +} + +void sse2_packuswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x67); + emit_modrm( p, dst, src ); +} + +void sse2_rcpps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x53); + emit_modrm( p, dst, src ); +} + +void sse2_rcpss( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0xF3, X86_TWOB, 0x53); + emit_modrm( p, dst, src ); +} + +void sse2_movd( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, 0x66, X86_TWOB); + emit_op_modrm( p, 0x6e, 0x7e, dst, src ); +} + + + + +/*********************************************************************** + * x87 instructions + */ +void x87_fist( struct x86_function *p, struct x86_reg dst ) +{ + emit_1ub(p, 0xdb); + emit_modrm_noreg(p, 2, dst); +} + +void x87_fistp( struct x86_function *p, struct x86_reg dst ) +{ + emit_1ub(p, 0xdb); + emit_modrm_noreg(p, 3, dst); +} + +void x87_fild( struct x86_function *p, struct x86_reg arg ) +{ + emit_1ub(p, 0xdf); + emit_modrm_noreg(p, 0, arg); +} + +void x87_fldz( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xee); +} + + +void x87_fldcw( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_REG32); + assert(arg.mod != mod_REG); + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 5, arg); +} + +void x87_fld1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe8); +} + +void x87_fldl2e( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xea); +} + +void x87_fldln2( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xed); +} + +void x87_fwait( struct x86_function *p ) +{ + emit_1ub(p, 0x9b); +} + +void x87_fnclex( struct x86_function *p ) +{ + emit_2ub(p, 0xdb, 0xe2); +} + +void x87_fclex( struct x86_function *p ) +{ + x87_fwait(p); + x87_fnclex(p); +} + + +static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, + unsigned char dst0ub0, + unsigned char dst0ub1, + unsigned char arg0ub0, + unsigned char arg0ub1, + unsigned char argmem_noreg) +{ + assert(dst.file == file_x87); + + if (arg.file == file_x87) { + if (dst.idx == 0) + emit_2ub(p, dst0ub0, dst0ub1+arg.idx); + else if (arg.idx == 0) + emit_2ub(p, arg0ub0, arg0ub1+arg.idx); + else + assert(0); + } + else if (dst.idx == 0) { + assert(arg.file == file_REG32); + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, argmem_noreg, arg); + } + else + assert(0); +} + +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xc8, + 0xdc, 0xc8, + 4); +} + +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xe0, + 0xdc, 0xe8, + 4); +} + +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xe8, + 0xdc, 0xe0, + 5); +} + +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xc0, + 0xdc, 0xc0, + 0); +} + +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xf0, + 0xdc, 0xf8, + 6); +} + +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +{ + x87_arith_op(p, dst, arg, + 0xd8, 0xf8, + 0xdc, 0xf0, + 7); +} + +void x87_fmulp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xc8+dst.idx); +} + +void x87_fsubp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xe8+dst.idx); +} + +void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xe0+dst.idx); +} + +void x87_faddp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xc0+dst.idx); +} + +void x87_fdivp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xf8+dst.idx); +} + +void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_x87); + assert(dst.idx >= 1); + emit_2ub(p, 0xde, 0xf0+dst.idx); +} + +void x87_fucom( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xdd, 0xe0+arg.idx); +} + +void x87_fucomp( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xdd, 0xe8+arg.idx); +} + +void x87_fucompp( struct x86_function *p ) +{ + emit_2ub(p, 0xda, 0xe9); +} + +void x87_fxch( struct x86_function *p, struct x86_reg arg ) +{ + assert(arg.file == file_x87); + emit_2ub(p, 0xd9, 0xc8+arg.idx); +} + +void x87_fabs( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe1); +} + +void x87_fchs( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xe0); +} + +void x87_fcos( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xff); +} + + +void x87_fprndint( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfc); +} + +void x87_fscale( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfd); +} + +void x87_fsin( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfe); +} + +void x87_fsincos( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfb); +} + +void x87_fsqrt( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xfa); +} + +void x87_fxtract( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf4); +} + +/* st0 = (2^st0)-1 + * + * Restrictions: -1.0 <= st0 <= 1.0 + */ +void x87_f2xm1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf0); +} + +/* st1 = st1 * log2(st0); + * pop_stack; + */ +void x87_fyl2x( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf1); +} + +/* st1 = st1 * log2(st0 + 1.0); + * pop_stack; + * + * A fast operation, with restrictions: -.29 < st0 < .29 + */ +void x87_fyl2xp1( struct x86_function *p ) +{ + emit_2ub(p, 0xd9, 0xf9); +} + + +void x87_fld( struct x86_function *p, struct x86_reg arg ) +{ + if (arg.file == file_x87) + emit_2ub(p, 0xd9, 0xc0 + arg.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 0, arg); + } +} + +void x87_fst( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xdd, 0xd0 + dst.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 2, dst); + } +} + +void x87_fstp( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xdd, 0xd8 + dst.idx); + else { + emit_1ub(p, 0xd9); + emit_modrm_noreg(p, 3, dst); + } +} + +void x87_fcom( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xd8, 0xd0 + dst.idx); + else { + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, 2, dst); + } +} + +void x87_fcomp( struct x86_function *p, struct x86_reg dst ) +{ + if (dst.file == file_x87) + emit_2ub(p, 0xd8, 0xd8 + dst.idx); + else { + emit_1ub(p, 0xd8); + emit_modrm_noreg(p, 3, dst); + } +} + + +void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) +{ + assert(dst.file == file_REG32); + + if (dst.idx == reg_AX && + dst.mod == mod_REG) + emit_2ub(p, 0xdf, 0xe0); + else { + emit_1ub(p, 0xdd); + emit_modrm_noreg(p, 7, dst); + } +} + + + + +/*********************************************************************** + * MMX instructions + */ + +void mmx_emms( struct x86_function *p ) +{ + assert(p->need_emms); + emit_2ub(p, 0x0f, 0x77); + p->need_emms = 0; +} + +void mmx_packssdw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_MMX || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x6b); + emit_modrm( p, dst, src ); +} + +void mmx_packuswb( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + assert(dst.file == file_MMX && + (src.file == file_MMX || src.mod != mod_REG)); + + p->need_emms = 1; + + emit_2ub(p, X86_TWOB, 0x67); + emit_modrm( p, dst, src ); +} + +void mmx_movd( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + p->need_emms = 1; + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x6e, 0x7e, dst, src ); +} + +void mmx_movq( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + p->need_emms = 1; + emit_1ub(p, X86_TWOB); + emit_op_modrm( p, 0x6f, 0x7f, dst, src ); +} + + +/*********************************************************************** + * Helper functions + */ + + +/* Retreive a reference to one of the function arguments, taking into + * account any push/pop activity: + */ +struct x86_reg x86_fn_arg( struct x86_function *p, + unsigned arg ) +{ + return x86_make_disp(x86_make_reg(file_REG32, reg_SP), + p->stack_offset + arg * 4); /* ??? */ +} + + +void x86_init_func( struct x86_function *p ) +{ + p->size = 0; + p->store = NULL; + p->csr = p->store; +} + +void x86_init_func_size( struct x86_function *p, unsigned code_size ) +{ + p->size = code_size; + p->store = rtasm_exec_malloc(code_size); + p->csr = p->store; +} + +void x86_release_func( struct x86_function *p ) +{ + rtasm_exec_free(p->store); + p->store = NULL; + p->csr = NULL; + p->size = 0; +} + + +void (*x86_get_func( struct x86_function *p ))(void) +{ + if (DISASSEM && p->store) + debug_printf("disassemble %p %p\n", p->store, p->csr); + return (void (*)(void)) (unsigned long) p->store; +} + +#else + +void x86sse_dummy( void ) +{ +} + +#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h new file mode 100644 index 0000000000..c2aa416492 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -0,0 +1,256 @@ + +#ifndef _X86SSE_H_ +#define _X86SSE_H_ + +#if defined(__i386__) || defined(__386__) + +/* It is up to the caller to ensure that instructions issued are + * suitable for the host cpu. There are no checks made in this module + * for mmx/sse/sse2 support on the cpu. + */ +struct x86_reg { + unsigned file:3; + unsigned idx:3; + unsigned mod:2; /* mod_REG if this is just a register */ + int disp:24; /* only +/- 23bits of offset - should be enough... */ +}; + +struct x86_function { + unsigned size; + unsigned char *store; + unsigned char *csr; + unsigned stack_offset; + int need_emms; + const char *fn; +}; + +enum x86_reg_file { + file_REG32, + file_MMX, + file_XMM, + file_x87 +}; + +/* Values for mod field of modr/m byte + */ +enum x86_reg_mod { + mod_INDIRECT, + mod_DISP8, + mod_DISP32, + mod_REG +}; + +enum x86_reg_name { + reg_AX, + reg_CX, + reg_DX, + reg_BX, + reg_SP, + reg_BP, + reg_SI, + reg_DI +}; + + +enum x86_cc { + cc_O, /* overflow */ + cc_NO, /* not overflow */ + cc_NAE, /* not above or equal / carry */ + cc_AE, /* above or equal / not carry */ + cc_E, /* equal / zero */ + cc_NE /* not equal / not zero */ +}; + +enum sse_cc { + cc_Equal, + cc_LessThan, + cc_LessThanEqual, + cc_Unordered, + cc_NotEqual, + cc_NotLessThan, + cc_NotLessThanEqual, + cc_Ordered +}; + +#define cc_Z cc_E +#define cc_NZ cc_NE + +/* Begin/end/retreive function creation: + */ + + +void x86_init_func( struct x86_function *p ); +void x86_init_func_size( struct x86_function *p, unsigned code_size ); +void x86_release_func( struct x86_function *p ); +void (*x86_get_func( struct x86_function *p ))( void ); + + + +/* Create and manipulate registers and regmem values: + */ +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ); + +struct x86_reg x86_make_disp( struct x86_reg reg, + int disp ); + +struct x86_reg x86_deref( struct x86_reg reg ); + +struct x86_reg x86_get_base_reg( struct x86_reg reg ); + + +/* Labels, jumps and fixup: + */ +unsigned char *x86_get_label( struct x86_function *p ); + +void x86_jcc( struct x86_function *p, + enum x86_cc cc, + unsigned char *label ); + +unsigned char *x86_jcc_forward( struct x86_function *p, + enum x86_cc cc ); + +unsigned char *x86_jmp_forward( struct x86_function *p); + +unsigned char *x86_call_forward( struct x86_function *p); + +void x86_fixup_fwd_jump( struct x86_function *p, + unsigned char *fixup ); + +void x86_jmp( struct x86_function *p, unsigned char *label ); + +/* void x86_call( struct x86_function *p, void (*label)() ); */ +void x86_call( struct x86_function *p, struct x86_reg reg); + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); + + +/* Macro for sse_shufps() and sse2_pshufd(): + */ +#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6)) +#define SHUF_NOOP RSW(0,1,2,3) +#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3) + +void mmx_emms( struct x86_function *p ); +void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); + +void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, + unsigned char shuf ); +void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); + +void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, + unsigned char cc ); +void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, + unsigned char shuf ); +void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); + +void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_dec( struct x86_function *p, struct x86_reg reg ); +void x86_inc( struct x86_function *p, struct x86_reg reg ); +void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mul( struct x86_function *p, struct x86_reg src ); +void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_pop( struct x86_function *p, struct x86_reg reg ); +void x86_push( struct x86_function *p, struct x86_reg reg ); +void x86_ret( struct x86_function *p ); +void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_sahf( struct x86_function *p ); + +void x87_f2xm1( struct x86_function *p ); +void x87_fabs( struct x86_function *p ); +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_faddp( struct x86_function *p, struct x86_reg dst ); +void x87_fchs( struct x86_function *p ); +void x87_fclex( struct x86_function *p ); +void x87_fcom( struct x86_function *p, struct x86_reg dst ); +void x87_fcomp( struct x86_function *p, struct x86_reg dst ); +void x87_fcos( struct x86_function *p ); +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fdivp( struct x86_function *p, struct x86_reg dst ); +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fdivrp( struct x86_function *p, struct x86_reg dst ); +void x87_fild( struct x86_function *p, struct x86_reg arg ); +void x87_fist( struct x86_function *p, struct x86_reg dst ); +void x87_fistp( struct x86_function *p, struct x86_reg dst ); +void x87_fld( struct x86_function *p, struct x86_reg arg ); +void x87_fld1( struct x86_function *p ); +void x87_fldcw( struct x86_function *p, struct x86_reg arg ); +void x87_fldl2e( struct x86_function *p ); +void x87_fldln2( struct x86_function *p ); +void x87_fldz( struct x86_function *p ); +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fmulp( struct x86_function *p, struct x86_reg dst ); +void x87_fnclex( struct x86_function *p ); +void x87_fprndint( struct x86_function *p ); +void x87_fscale( struct x86_function *p ); +void x87_fsin( struct x86_function *p ); +void x87_fsincos( struct x86_function *p ); +void x87_fsqrt( struct x86_function *p ); +void x87_fst( struct x86_function *p, struct x86_reg dst ); +void x87_fstp( struct x86_function *p, struct x86_reg dst ); +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fsubp( struct x86_function *p, struct x86_reg dst ); +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); +void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); +void x87_fxch( struct x86_function *p, struct x86_reg dst ); +void x87_fxtract( struct x86_function *p ); +void x87_fyl2x( struct x86_function *p ); +void x87_fyl2xp1( struct x86_function *p ); +void x87_fwait( struct x86_function *p ); +void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); +void x87_fucompp( struct x86_function *p ); +void x87_fucomp( struct x86_function *p, struct x86_reg arg ); +void x87_fucom( struct x86_function *p, struct x86_reg arg ); + + + +/* Retreive a reference to one of the function arguments, taking into + * account any push/pop activity. Note - doesn't track explict + * manipulation of ESP by other instructions. + */ +struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); + +#endif +#endif diff --git a/src/gallium/auxiliary/rtasm/x86sse.c b/src/gallium/auxiliary/rtasm/x86sse.c deleted file mode 100644 index fff6f77a6b..0000000000 --- a/src/gallium/auxiliary/rtasm/x86sse.c +++ /dev/null @@ -1,1195 +0,0 @@ -#if defined(__i386__) || defined(__386__) - -#include "pipe/p_compiler.h" -#include "pipe/p_debug.h" - -#include "x86sse.h" - -#define DISASSEM 0 -#define X86_TWOB 0x0f - -static unsigned char *cptr( void (*label)() ) -{ - return (unsigned char *)(unsigned long)label; -} - - -static void do_realloc( struct x86_function *p ) -{ - if (p->size == 0) { - p->size = 1024; - p->store = _mesa_exec_malloc(p->size); - p->csr = p->store; - } - else { - unsigned used = p->csr - p->store; - unsigned char *tmp = p->store; - p->size *= 2; - p->store = _mesa_exec_malloc(p->size); - memcpy(p->store, tmp, used); - p->csr = p->store + used; - _mesa_exec_free(tmp); - } -} - -/* Emit bytes to the instruction stream: - */ -static unsigned char *reserve( struct x86_function *p, int bytes ) -{ - if (p->csr + bytes - p->store > p->size) - do_realloc(p); - - { - unsigned char *csr = p->csr; - p->csr += bytes; - return csr; - } -} - - - -static void emit_1b( struct x86_function *p, char b0 ) -{ - char *csr = (char *)reserve(p, 1); - *csr = b0; -} - -static void emit_1i( struct x86_function *p, int i0 ) -{ - int *icsr = (int *)reserve(p, sizeof(i0)); - *icsr = i0; -} - -static void emit_1ub( struct x86_function *p, unsigned char b0 ) -{ - unsigned char *csr = reserve(p, 1); - *csr++ = b0; -} - -static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 ) -{ - unsigned char *csr = reserve(p, 2); - *csr++ = b0; - *csr++ = b1; -} - -static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 ) -{ - unsigned char *csr = reserve(p, 3); - *csr++ = b0; - *csr++ = b1; - *csr++ = b2; -} - - -/* Build a modRM byte + possible displacement. No treatment of SIB - * indexing. BZZT - no way to encode an absolute address. - */ -static void emit_modrm( struct x86_function *p, - struct x86_reg reg, - struct x86_reg regmem ) -{ - unsigned char val = 0; - - assert(reg.mod == mod_REG); - - val |= regmem.mod << 6; /* mod field */ - val |= reg.idx << 3; /* reg field */ - val |= regmem.idx; /* r/m field */ - - emit_1ub(p, val); - - /* Oh-oh we've stumbled into the SIB thing. - */ - if (regmem.file == file_REG32 && - regmem.idx == reg_SP) { - emit_1ub(p, 0x24); /* simplistic! */ - } - - switch (regmem.mod) { - case mod_REG: - case mod_INDIRECT: - break; - case mod_DISP8: - emit_1b(p, regmem.disp); - break; - case mod_DISP32: - emit_1i(p, regmem.disp); - break; - default: - assert(0); - break; - } -} - - -static void emit_modrm_noreg( struct x86_function *p, - unsigned op, - struct x86_reg regmem ) -{ - struct x86_reg dummy = x86_make_reg(file_REG32, op); - emit_modrm(p, dummy, regmem); -} - -/* Many x86 instructions have two opcodes to cope with the situations - * where the destination is a register or memory reference - * respectively. This function selects the correct opcode based on - * the arguments presented. - */ -static void emit_op_modrm( struct x86_function *p, - unsigned char op_dst_is_reg, - unsigned char op_dst_is_mem, - struct x86_reg dst, - struct x86_reg src ) -{ - switch (dst.mod) { - case mod_REG: - emit_1ub(p, op_dst_is_reg); - emit_modrm(p, dst, src); - break; - case mod_INDIRECT: - case mod_DISP32: - case mod_DISP8: - assert(src.mod == mod_REG); - emit_1ub(p, op_dst_is_mem); - emit_modrm(p, src, dst); - break; - default: - assert(0); - break; - } -} - - - - - - - -/* Create and manipulate registers and regmem values: - */ -struct x86_reg x86_make_reg( enum x86_reg_file file, - enum x86_reg_name idx ) -{ - struct x86_reg reg; - - reg.file = file; - reg.idx = idx; - reg.mod = mod_REG; - reg.disp = 0; - - return reg; -} - -struct x86_reg x86_make_disp( struct x86_reg reg, - int disp ) -{ - assert(reg.file == file_REG32); - - if (reg.mod == mod_REG) - reg.disp = disp; - else - reg.disp += disp; - - if (reg.disp == 0) - reg.mod = mod_INDIRECT; - else if (reg.disp <= 127 && reg.disp >= -128) - reg.mod = mod_DISP8; - else - reg.mod = mod_DISP32; - - return reg; -} - -struct x86_reg x86_deref( struct x86_reg reg ) -{ - return x86_make_disp(reg, 0); -} - -struct x86_reg x86_get_base_reg( struct x86_reg reg ) -{ - return x86_make_reg( reg.file, reg.idx ); -} - -unsigned char *x86_get_label( struct x86_function *p ) -{ - return p->csr; -} - - - -/*********************************************************************** - * x86 instructions - */ - - -void x86_jcc( struct x86_function *p, - enum x86_cc cc, - unsigned char *label ) -{ - int offset = label - (x86_get_label(p) + 2); - - if (offset <= 127 && offset >= -128) { - emit_1ub(p, 0x70 + cc); - emit_1b(p, (char) offset); - } - else { - offset = label - (x86_get_label(p) + 6); - emit_2ub(p, 0x0f, 0x80 + cc); - emit_1i(p, offset); - } -} - -/* Always use a 32bit offset for forward jumps: - */ -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ) -{ - emit_2ub(p, 0x0f, 0x80 + cc); - emit_1i(p, 0); - return x86_get_label(p); -} - -unsigned char *x86_jmp_forward( struct x86_function *p) -{ - emit_1ub(p, 0xe9); - emit_1i(p, 0); - return x86_get_label(p); -} - -unsigned char *x86_call_forward( struct x86_function *p) -{ - emit_1ub(p, 0xe8); - emit_1i(p, 0); - return x86_get_label(p); -} - -/* Fixup offset from forward jump: - */ -void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ) -{ - *(int *)(fixup - 4) = x86_get_label(p) - fixup; -} - -void x86_jmp( struct x86_function *p, unsigned char *label) -{ - emit_1ub(p, 0xe9); - emit_1i(p, label - x86_get_label(p) - 4); -} - -#if 0 -/* This doesn't work once we start reallocating & copying the - * generated code on buffer fills, because the call is relative to the - * current pc. - */ -void x86_call( struct x86_function *p, void (*label)()) -{ - emit_1ub(p, 0xe8); - emit_1i(p, cptr(label) - x86_get_label(p) - 4); -} -#else -void x86_call( struct x86_function *p, struct x86_reg reg) -{ - emit_1ub(p, 0xff); - emit_modrm(p, reg, reg); -} -#endif - - -/* michal: - * Temporary. As I need immediate operands, and dont want to mess with the codegen, - * I load the immediate into general purpose register and use it. - */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) -{ - assert(dst.mod == mod_REG); - emit_1ub(p, 0xb8 + dst.idx); - emit_1i(p, imm); -} - -void x86_push( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x50 + reg.idx); - p->stack_offset += 4; -} - -void x86_pop( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x58 + reg.idx); - p->stack_offset -= 4; -} - -void x86_inc( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x40 + reg.idx); -} - -void x86_dec( struct x86_function *p, - struct x86_reg reg ) -{ - assert(reg.mod == mod_REG); - emit_1ub(p, 0x48 + reg.idx); -} - -void x86_ret( struct x86_function *p ) -{ - emit_1ub(p, 0xc3); -} - -void x86_sahf( struct x86_function *p ) -{ - emit_1ub(p, 0x9e); -} - -void x86_mov( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x8b, 0x89, dst, src ); -} - -void x86_xor( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x33, 0x31, dst, src ); -} - -void x86_cmp( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x3b, 0x39, dst, src ); -} - -void x86_lea( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, 0x8d); - emit_modrm( p, dst, src ); -} - -void x86_test( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, 0x85); - emit_modrm( p, dst, src ); -} - -void x86_add( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm(p, 0x03, 0x01, dst, src ); -} - -void x86_mul( struct x86_function *p, - struct x86_reg src ) -{ - assert (src.file == file_REG32 && src.mod == mod_REG); - emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); -} - -void x86_sub( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm(p, 0x2b, 0x29, dst, src ); -} - -void x86_or( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x0b, 0x09, dst, src ); -} - -void x86_and( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_op_modrm( p, 0x23, 0x21, dst, src ); -} - - - -/*********************************************************************** - * SSE instructions - */ - - -void sse_movss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, 0xF3, X86_TWOB); - emit_op_modrm( p, 0x10, 0x11, dst, src ); -} - -void sse_movaps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x28, 0x29, dst, src ); -} - -void sse_movups( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x10, 0x11, dst, src ); -} - -void sse_movhps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod != mod_REG || src.mod != mod_REG); - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ -} - -void sse_movlps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod != mod_REG || src.mod != mod_REG); - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ -} - -void sse_maxps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5F); - emit_modrm( p, dst, src ); -} - -void sse_maxss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x5F); - emit_modrm( p, dst, src ); -} - -void sse_divss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x5E); - emit_modrm( p, dst, src ); -} - -void sse_minps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5D); - emit_modrm( p, dst, src ); -} - -void sse_subps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x5C); - emit_modrm( p, dst, src ); -} - -void sse_mulps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x59); - emit_modrm( p, dst, src ); -} - -void sse_mulss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x59); - emit_modrm( p, dst, src ); -} - -void sse_addps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x58); - emit_modrm( p, dst, src ); -} - -void sse_addss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x58); - emit_modrm( p, dst, src ); -} - -void sse_andnps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x55); - emit_modrm( p, dst, src ); -} - -void sse_andps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x54); - emit_modrm( p, dst, src ); -} - -void sse_rsqrtps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x52); - emit_modrm( p, dst, src ); -} - -void sse_rsqrtss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x52); - emit_modrm( p, dst, src ); - -} - -void sse_movhlps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod == mod_REG && src.mod == mod_REG); - emit_2ub(p, X86_TWOB, 0x12); - emit_modrm( p, dst, src ); -} - -void sse_movlhps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.mod == mod_REG && src.mod == mod_REG); - emit_2ub(p, X86_TWOB, 0x16); - emit_modrm( p, dst, src ); -} - -void sse_orps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x56); - emit_modrm( p, dst, src ); -} - -void sse_xorps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x57); - emit_modrm( p, dst, src ); -} - -void sse_cvtps2pi( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_XMM || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x2d); - emit_modrm( p, dst, src ); -} - - -/* Shufps can also be used to implement a reduced swizzle when dest == - * arg0. - */ -void sse_shufps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char shuf) -{ - emit_2ub(p, X86_TWOB, 0xC6); - emit_modrm(p, dest, arg0); - emit_1ub(p, shuf); -} - -void sse_cmpps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char cc) -{ - emit_2ub(p, X86_TWOB, 0xC2); - emit_modrm(p, dest, arg0); - emit_1ub(p, cc); -} - -void sse_pmovmskb( struct x86_function *p, - struct x86_reg dest, - struct x86_reg src) -{ - emit_3ub(p, 0x66, X86_TWOB, 0xD7); - emit_modrm(p, dest, src); -} - -/*********************************************************************** - * SSE2 instructions - */ - -/** - * Perform a reduced swizzle: - */ -void sse2_pshufd( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, - unsigned char shuf) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x70); - emit_modrm(p, dest, arg0); - emit_1ub(p, shuf); -} - -void sse2_cvttps2dq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); - emit_modrm( p, dst, src ); -} - -void sse2_cvtps2dq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x5B); - emit_modrm( p, dst, src ); -} - -void sse2_packssdw( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x6B); - emit_modrm( p, dst, src ); -} - -void sse2_packsswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x63); - emit_modrm( p, dst, src ); -} - -void sse2_packuswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0x66, X86_TWOB, 0x67); - emit_modrm( p, dst, src ); -} - -void sse2_rcpps( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, X86_TWOB, 0x53); - emit_modrm( p, dst, src ); -} - -void sse2_rcpss( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_3ub(p, 0xF3, X86_TWOB, 0x53); - emit_modrm( p, dst, src ); -} - -void sse2_movd( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - emit_2ub(p, 0x66, X86_TWOB); - emit_op_modrm( p, 0x6e, 0x7e, dst, src ); -} - - - - -/*********************************************************************** - * x87 instructions - */ -void x87_fist( struct x86_function *p, struct x86_reg dst ) -{ - emit_1ub(p, 0xdb); - emit_modrm_noreg(p, 2, dst); -} - -void x87_fistp( struct x86_function *p, struct x86_reg dst ) -{ - emit_1ub(p, 0xdb); - emit_modrm_noreg(p, 3, dst); -} - -void x87_fild( struct x86_function *p, struct x86_reg arg ) -{ - emit_1ub(p, 0xdf); - emit_modrm_noreg(p, 0, arg); -} - -void x87_fldz( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xee); -} - - -void x87_fldcw( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_REG32); - assert(arg.mod != mod_REG); - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 5, arg); -} - -void x87_fld1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe8); -} - -void x87_fldl2e( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xea); -} - -void x87_fldln2( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xed); -} - -void x87_fwait( struct x86_function *p ) -{ - emit_1ub(p, 0x9b); -} - -void x87_fnclex( struct x86_function *p ) -{ - emit_2ub(p, 0xdb, 0xe2); -} - -void x87_fclex( struct x86_function *p ) -{ - x87_fwait(p); - x87_fnclex(p); -} - - -static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg, - unsigned char dst0ub0, - unsigned char dst0ub1, - unsigned char arg0ub0, - unsigned char arg0ub1, - unsigned char argmem_noreg) -{ - assert(dst.file == file_x87); - - if (arg.file == file_x87) { - if (dst.idx == 0) - emit_2ub(p, dst0ub0, dst0ub1+arg.idx); - else if (arg.idx == 0) - emit_2ub(p, arg0ub0, arg0ub1+arg.idx); - else - assert(0); - } - else if (dst.idx == 0) { - assert(arg.file == file_REG32); - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, argmem_noreg, arg); - } - else - assert(0); -} - -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xc8, - 0xdc, 0xc8, - 4); -} - -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xe0, - 0xdc, 0xe8, - 4); -} - -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xe8, - 0xdc, 0xe0, - 5); -} - -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xc0, - 0xdc, 0xc0, - 0); -} - -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xf0, - 0xdc, 0xf8, - 6); -} - -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) -{ - x87_arith_op(p, dst, arg, - 0xd8, 0xf8, - 0xdc, 0xf0, - 7); -} - -void x87_fmulp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xc8+dst.idx); -} - -void x87_fsubp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xe8+dst.idx); -} - -void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xe0+dst.idx); -} - -void x87_faddp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xc0+dst.idx); -} - -void x87_fdivp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xf8+dst.idx); -} - -void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_x87); - assert(dst.idx >= 1); - emit_2ub(p, 0xde, 0xf0+dst.idx); -} - -void x87_fucom( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xdd, 0xe0+arg.idx); -} - -void x87_fucomp( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xdd, 0xe8+arg.idx); -} - -void x87_fucompp( struct x86_function *p ) -{ - emit_2ub(p, 0xda, 0xe9); -} - -void x87_fxch( struct x86_function *p, struct x86_reg arg ) -{ - assert(arg.file == file_x87); - emit_2ub(p, 0xd9, 0xc8+arg.idx); -} - -void x87_fabs( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe1); -} - -void x87_fchs( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xe0); -} - -void x87_fcos( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xff); -} - - -void x87_fprndint( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfc); -} - -void x87_fscale( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfd); -} - -void x87_fsin( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfe); -} - -void x87_fsincos( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfb); -} - -void x87_fsqrt( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xfa); -} - -void x87_fxtract( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf4); -} - -/* st0 = (2^st0)-1 - * - * Restrictions: -1.0 <= st0 <= 1.0 - */ -void x87_f2xm1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf0); -} - -/* st1 = st1 * log2(st0); - * pop_stack; - */ -void x87_fyl2x( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf1); -} - -/* st1 = st1 * log2(st0 + 1.0); - * pop_stack; - * - * A fast operation, with restrictions: -.29 < st0 < .29 - */ -void x87_fyl2xp1( struct x86_function *p ) -{ - emit_2ub(p, 0xd9, 0xf9); -} - - -void x87_fld( struct x86_function *p, struct x86_reg arg ) -{ - if (arg.file == file_x87) - emit_2ub(p, 0xd9, 0xc0 + arg.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 0, arg); - } -} - -void x87_fst( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xdd, 0xd0 + dst.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 2, dst); - } -} - -void x87_fstp( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xdd, 0xd8 + dst.idx); - else { - emit_1ub(p, 0xd9); - emit_modrm_noreg(p, 3, dst); - } -} - -void x87_fcom( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xd8, 0xd0 + dst.idx); - else { - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, 2, dst); - } -} - -void x87_fcomp( struct x86_function *p, struct x86_reg dst ) -{ - if (dst.file == file_x87) - emit_2ub(p, 0xd8, 0xd8 + dst.idx); - else { - emit_1ub(p, 0xd8); - emit_modrm_noreg(p, 3, dst); - } -} - - -void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) -{ - assert(dst.file == file_REG32); - - if (dst.idx == reg_AX && - dst.mod == mod_REG) - emit_2ub(p, 0xdf, 0xe0); - else { - emit_1ub(p, 0xdd); - emit_modrm_noreg(p, 7, dst); - } -} - - - - -/*********************************************************************** - * MMX instructions - */ - -void mmx_emms( struct x86_function *p ) -{ - assert(p->need_emms); - emit_2ub(p, 0x0f, 0x77); - p->need_emms = 0; -} - -void mmx_packssdw( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_MMX || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x6b); - emit_modrm( p, dst, src ); -} - -void mmx_packuswb( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - assert(dst.file == file_MMX && - (src.file == file_MMX || src.mod != mod_REG)); - - p->need_emms = 1; - - emit_2ub(p, X86_TWOB, 0x67); - emit_modrm( p, dst, src ); -} - -void mmx_movd( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - p->need_emms = 1; - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x6e, 0x7e, dst, src ); -} - -void mmx_movq( struct x86_function *p, - struct x86_reg dst, - struct x86_reg src ) -{ - p->need_emms = 1; - emit_1ub(p, X86_TWOB); - emit_op_modrm( p, 0x6f, 0x7f, dst, src ); -} - - -/*********************************************************************** - * Helper functions - */ - - -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity: - */ -struct x86_reg x86_fn_arg( struct x86_function *p, - unsigned arg ) -{ - return x86_make_disp(x86_make_reg(file_REG32, reg_SP), - p->stack_offset + arg * 4); /* ??? */ -} - - -void x86_init_func( struct x86_function *p ) -{ - p->size = 0; - p->store = NULL; - p->csr = p->store; -} - -void x86_init_func_size( struct x86_function *p, unsigned code_size ) -{ - p->size = code_size; - p->store = _mesa_exec_malloc(code_size); - p->csr = p->store; -} - -void x86_release_func( struct x86_function *p ) -{ - _mesa_exec_free(p->store); - p->store = NULL; - p->csr = NULL; - p->size = 0; -} - - -void (*x86_get_func( struct x86_function *p ))(void) -{ - if (DISASSEM && p->store) - _mesa_printf("disassemble %p %p\n", p->store, p->csr); - return (void (*)(void)) (unsigned long) p->store; -} - -#else - -void x86sse_dummy( void ) -{ -} - -#endif diff --git a/src/gallium/auxiliary/rtasm/x86sse.h b/src/gallium/auxiliary/rtasm/x86sse.h deleted file mode 100644 index c2aa416492..0000000000 --- a/src/gallium/auxiliary/rtasm/x86sse.h +++ /dev/null @@ -1,256 +0,0 @@ - -#ifndef _X86SSE_H_ -#define _X86SSE_H_ - -#if defined(__i386__) || defined(__386__) - -/* It is up to the caller to ensure that instructions issued are - * suitable for the host cpu. There are no checks made in this module - * for mmx/sse/sse2 support on the cpu. - */ -struct x86_reg { - unsigned file:3; - unsigned idx:3; - unsigned mod:2; /* mod_REG if this is just a register */ - int disp:24; /* only +/- 23bits of offset - should be enough... */ -}; - -struct x86_function { - unsigned size; - unsigned char *store; - unsigned char *csr; - unsigned stack_offset; - int need_emms; - const char *fn; -}; - -enum x86_reg_file { - file_REG32, - file_MMX, - file_XMM, - file_x87 -}; - -/* Values for mod field of modr/m byte - */ -enum x86_reg_mod { - mod_INDIRECT, - mod_DISP8, - mod_DISP32, - mod_REG -}; - -enum x86_reg_name { - reg_AX, - reg_CX, - reg_DX, - reg_BX, - reg_SP, - reg_BP, - reg_SI, - reg_DI -}; - - -enum x86_cc { - cc_O, /* overflow */ - cc_NO, /* not overflow */ - cc_NAE, /* not above or equal / carry */ - cc_AE, /* above or equal / not carry */ - cc_E, /* equal / zero */ - cc_NE /* not equal / not zero */ -}; - -enum sse_cc { - cc_Equal, - cc_LessThan, - cc_LessThanEqual, - cc_Unordered, - cc_NotEqual, - cc_NotLessThan, - cc_NotLessThanEqual, - cc_Ordered -}; - -#define cc_Z cc_E -#define cc_NZ cc_NE - -/* Begin/end/retreive function creation: - */ - - -void x86_init_func( struct x86_function *p ); -void x86_init_func_size( struct x86_function *p, unsigned code_size ); -void x86_release_func( struct x86_function *p ); -void (*x86_get_func( struct x86_function *p ))( void ); - - - -/* Create and manipulate registers and regmem values: - */ -struct x86_reg x86_make_reg( enum x86_reg_file file, - enum x86_reg_name idx ); - -struct x86_reg x86_make_disp( struct x86_reg reg, - int disp ); - -struct x86_reg x86_deref( struct x86_reg reg ); - -struct x86_reg x86_get_base_reg( struct x86_reg reg ); - - -/* Labels, jumps and fixup: - */ -unsigned char *x86_get_label( struct x86_function *p ); - -void x86_jcc( struct x86_function *p, - enum x86_cc cc, - unsigned char *label ); - -unsigned char *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ); - -unsigned char *x86_jmp_forward( struct x86_function *p); - -unsigned char *x86_call_forward( struct x86_function *p); - -void x86_fixup_fwd_jump( struct x86_function *p, - unsigned char *fixup ); - -void x86_jmp( struct x86_function *p, unsigned char *label ); - -/* void x86_call( struct x86_function *p, void (*label)() ); */ -void x86_call( struct x86_function *p, struct x86_reg reg); - -/* michal: - * Temporary. As I need immediate operands, and dont want to mess with the codegen, - * I load the immediate into general purpose register and use it. - */ -void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ); - - -/* Macro for sse_shufps() and sse2_pshufd(): - */ -#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6)) -#define SHUF_NOOP RSW(0,1,2,3) -#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3) - -void mmx_emms( struct x86_function *p ); -void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); - -void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, - unsigned char shuf ); -void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); - -void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src, - unsigned char cc ); -void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, - unsigned char shuf ); -void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); - -void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_dec( struct x86_function *p, struct x86_reg reg ); -void x86_inc( struct x86_function *p, struct x86_reg reg ); -void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mul( struct x86_function *p, struct x86_reg src ); -void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_pop( struct x86_function *p, struct x86_reg reg ); -void x86_push( struct x86_function *p, struct x86_reg reg ); -void x86_ret( struct x86_function *p ); -void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_sahf( struct x86_function *p ); - -void x87_f2xm1( struct x86_function *p ); -void x87_fabs( struct x86_function *p ); -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_faddp( struct x86_function *p, struct x86_reg dst ); -void x87_fchs( struct x86_function *p ); -void x87_fclex( struct x86_function *p ); -void x87_fcom( struct x86_function *p, struct x86_reg dst ); -void x87_fcomp( struct x86_function *p, struct x86_reg dst ); -void x87_fcos( struct x86_function *p ); -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fdivp( struct x86_function *p, struct x86_reg dst ); -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fdivrp( struct x86_function *p, struct x86_reg dst ); -void x87_fild( struct x86_function *p, struct x86_reg arg ); -void x87_fist( struct x86_function *p, struct x86_reg dst ); -void x87_fistp( struct x86_function *p, struct x86_reg dst ); -void x87_fld( struct x86_function *p, struct x86_reg arg ); -void x87_fld1( struct x86_function *p ); -void x87_fldcw( struct x86_function *p, struct x86_reg arg ); -void x87_fldl2e( struct x86_function *p ); -void x87_fldln2( struct x86_function *p ); -void x87_fldz( struct x86_function *p ); -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fmulp( struct x86_function *p, struct x86_reg dst ); -void x87_fnclex( struct x86_function *p ); -void x87_fprndint( struct x86_function *p ); -void x87_fscale( struct x86_function *p ); -void x87_fsin( struct x86_function *p ); -void x87_fsincos( struct x86_function *p ); -void x87_fsqrt( struct x86_function *p ); -void x87_fst( struct x86_function *p, struct x86_reg dst ); -void x87_fstp( struct x86_function *p, struct x86_reg dst ); -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fsubp( struct x86_function *p, struct x86_reg dst ); -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ); -void x87_fsubrp( struct x86_function *p, struct x86_reg dst ); -void x87_fxch( struct x86_function *p, struct x86_reg dst ); -void x87_fxtract( struct x86_function *p ); -void x87_fyl2x( struct x86_function *p ); -void x87_fyl2xp1( struct x86_function *p ); -void x87_fwait( struct x86_function *p ); -void x87_fnstsw( struct x86_function *p, struct x86_reg dst ); -void x87_fucompp( struct x86_function *p ); -void x87_fucomp( struct x86_function *p, struct x86_reg arg ); -void x87_fucom( struct x86_function *p, struct x86_reg arg ); - - - -/* Retreive a reference to one of the function arguments, taking into - * account any push/pop activity. Note - doesn't track explict - * manipulation of ESP by other instructions. - */ -struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg ); - -#endif -#endif -- cgit v1.2.3 From d2f6c9ab10656f6ecda131a6785a60565026d249 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 12:05:32 +0900 Subject: Add copyright headers to all rtasm source files. --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 23 +++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 28 +++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 3c885a9fff..b332192a62 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -1,3 +1,26 @@ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + #if defined(__i386__) || defined(__386__) #include "pipe/p_compiler.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index c2aa416492..e4576001bf 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -1,6 +1,28 @@ - -#ifndef _X86SSE_H_ -#define _X86SSE_H_ +/************************************************************************** + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _RTASM_X86SSE_H_ +#define _RTASM_X86SSE_H_ #if defined(__i386__) || defined(__386__) -- cgit v1.2.3 From 17158c2f00f5bee29ec8239367fd5498f22e4a91 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 12:24:42 +0900 Subject: Move mm.c code into util module. Using the u_ prefix to distingish the c source files that support gallium interfaces and those that have really no relation with gallium itself. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 302 +----------------------- src/gallium/auxiliary/rtasm/Makefile | 5 +- src/gallium/auxiliary/rtasm/SConscript | 3 +- src/gallium/auxiliary/rtasm/mm.c | 283 ---------------------- src/gallium/auxiliary/rtasm/mm.h | 89 ------- src/gallium/auxiliary/rtasm/rtasm_execmem.c | 2 +- src/gallium/auxiliary/util/Makefile | 3 +- src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/u_mm.c | 283 ++++++++++++++++++++++ src/gallium/auxiliary/util/u_mm.h | 91 +++++++ 10 files changed, 382 insertions(+), 680 deletions(-) delete mode 100644 src/gallium/auxiliary/rtasm/mm.c delete mode 100644 src/gallium/auxiliary/rtasm/mm.h create mode 100644 src/gallium/auxiliary/util/u_mm.c create mode 100644 src/gallium/auxiliary/util/u_mm.h (limited to 'src') diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 969aab51b5..983a105347 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -1,7 +1,6 @@ /************************************************************************** * * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright 1999 Wittawat Yamwong * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -40,6 +39,7 @@ #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_util.h" +#include "util/u_mm.h" #include "pb_buffer.h" #include "pb_bufmgr.h" @@ -50,306 +50,6 @@ #define SUPER(__derived) (&(__derived)->base) -struct mem_block -{ - struct mem_block *next, *prev; - struct mem_block *next_free, *prev_free; - struct mem_block *heap; - int ofs, size; - unsigned int free:1; - unsigned int reserved:1; -}; - - -#ifdef DEBUG -/** - * For debugging purposes. - */ -static void -mmDumpMemInfo(const struct mem_block *heap) -{ - debug_printf("Memory heap %p:\n", (void *)heap); - if (heap == 0) { - debug_printf(" heap == 0\n"); - } else { - const struct mem_block *p; - - for(p = heap->next; p != heap; p = p->next) { - debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - debug_printf("\nFree list:\n"); - - for(p = heap->next_free; p != heap; p = p->next_free) { - debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - } - debug_printf("End of memory blocks\n"); -} -#endif - - -/** - * input: total size in bytes - * return: a heap pointer if OK, NULL if error - */ -static struct mem_block * -mmInit(int ofs, int size) -{ - struct mem_block *heap, *block; - - if (size <= 0) - return NULL; - - heap = CALLOC_STRUCT(mem_block); - if (!heap) - return NULL; - - block = CALLOC_STRUCT(mem_block); - if (!block) { - FREE(heap); - return NULL; - } - - heap->next = block; - heap->prev = block; - heap->next_free = block; - heap->prev_free = block; - - block->heap = heap; - block->next = heap; - block->prev = heap; - block->next_free = heap; - block->prev_free = heap; - - block->ofs = ofs; - block->size = size; - block->free = 1; - - return heap; -} - - -static struct mem_block * -SliceBlock(struct mem_block *p, - int startofs, int size, - int reserved, int alignment) -{ - struct mem_block *newblock; - - /* break left [p, newblock, p->next], then p = newblock */ - if (startofs > p->ofs) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs; - newblock->size = p->size - (startofs - p->ofs); - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size -= newblock->size; - p = newblock; - } - - /* break right, also [p, newblock, p->next] */ - if (size < p->size) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs + size; - newblock->size = p->size - size; - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size = size; - } - - /* p = middle block */ - p->free = 0; - - /* Remove p from the free list: - */ - p->next_free->prev_free = p->prev_free; - p->prev_free->next_free = p->next_free; - - p->next_free = 0; - p->prev_free = 0; - - p->reserved = reserved; - return p; -} - - -/** - * Allocate 'size' bytes with 2^align2 bytes alignment, - * restrict the search to free memory after 'startSearch' - * depth and back buffers should be in different 4mb banks - * to get better page hits if possible - * input: size = size of block - * align2 = 2^align2 bytes alignment - * startSearch = linear offset from start of heap to begin search - * return: pointer to the allocated block, 0 if error - */ -static struct mem_block * -mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) -{ - struct mem_block *p; - const int mask = (1 << align2)-1; - int startofs = 0; - int endofs; - - if (!heap || align2 < 0 || size <= 0) - return NULL; - - for (p = heap->next_free; p != heap; p = p->next_free) { - assert(p->free); - - startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { - startofs = startSearch; - } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) - break; - } - - if (p == heap) - return NULL; - - assert(p->free); - p = SliceBlock(p,startofs,size,0,mask+1); - - return p; -} - - -#if 0 -/** - * Free block starts at offset - * input: pointer to a heap, start offset - * return: pointer to a block - */ -static struct mem_block * -mmFindBlock(struct mem_block *heap, int start) -{ - struct mem_block *p; - - for (p = heap->next; p != heap; p = p->next) { - if (p->ofs == start) - return p; - } - - return NULL; -} -#endif - - -static INLINE int -Join2Blocks(struct mem_block *p) -{ - /* XXX there should be some assertions here */ - - /* NOTE: heap->free == 0 */ - - if (p->free && p->next->free) { - struct mem_block *q = p->next; - - assert(p->ofs + p->size == q->ofs); - p->size += q->size; - - p->next = q->next; - q->next->prev = p; - - q->next_free->prev_free = q->prev_free; - q->prev_free->next_free = q->next_free; - - FREE(q); - return 1; - } - return 0; -} - - -/** - * Free block starts at offset - * input: pointer to a block - * return: 0 if OK, -1 if error - */ -static int -mmFreeMem(struct mem_block *b) -{ - if (!b) - return 0; - - if (b->free) { - debug_printf("block already free\n"); - return -1; - } - if (b->reserved) { - debug_printf("block is reserved\n"); - return -1; - } - - b->free = 1; - b->next_free = b->heap->next_free; - b->prev_free = b->heap; - b->next_free->prev_free = b; - b->prev_free->next_free = b; - - Join2Blocks(b); - if (b->prev != b->heap) - Join2Blocks(b->prev); - - return 0; -} - - -/** - * destroy MM - */ -static void -mmDestroy(struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap) - return; - - for (p = heap->next; p != heap; ) { - struct mem_block *next = p->next; - FREE(p); - p = next; - } - - FREE(heap); -} - - struct mm_pb_manager { struct pb_manager base; diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index 7c8ac60794..edfae2a204 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -5,9 +5,8 @@ include $(TOP)/configs/current LIBNAME = rtasm DRIVER_SOURCES = \ - execmem.c \ - x86sse.c \ - mm.c + rtasm_execmem.c \ + rtasm_x86sse.c C_SOURCES = \ $(DRIVER_SOURCES) diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index de8456e0ca..6eca1fe4c0 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -4,8 +4,7 @@ rtasm = env.ConvenienceLibrary( target = 'rtasm', source = [ 'rtasm_execmem.c', - 'rtasm_x86sse.c', - 'mm.c', + 'rtasm_x86sse.c' ]) auxiliaries.insert(0, rtasm) diff --git a/src/gallium/auxiliary/rtasm/mm.c b/src/gallium/auxiliary/rtasm/mm.c deleted file mode 100644 index 15f50491da..0000000000 --- a/src/gallium/auxiliary/rtasm/mm.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * GLX Hardware Device Driver common code - * Copyright (C) 1999 Wittawat Yamwong - * - * 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 - * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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 "pipe/p_compiler.h" -#include "pipe/p_util.h" -#include "pipe/p_debug.h" - -#include "mm.h" - - -void -mmDumpMemInfo(const struct mem_block *heap) -{ - debug_printf("Memory heap %p:\n", (void *)heap); - if (heap == 0) { - debug_printf(" heap == 0\n"); - } else { - const struct mem_block *p; - - for(p = heap->next; p != heap; p = p->next) { - debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - debug_printf("\nFree list:\n"); - - for(p = heap->next_free; p != heap; p = p->next_free) { - debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, - p->free ? 'F':'.', - p->reserved ? 'R':'.'); - } - - } - debug_printf("End of memory blocks\n"); -} - -struct mem_block * -mmInit(int ofs, int size) -{ - struct mem_block *heap, *block; - - if (size <= 0) - return NULL; - - heap = CALLOC_STRUCT(mem_block); - if (!heap) - return NULL; - - block = CALLOC_STRUCT(mem_block); - if (!block) { - FREE(heap); - return NULL; - } - - heap->next = block; - heap->prev = block; - heap->next_free = block; - heap->prev_free = block; - - block->heap = heap; - block->next = heap; - block->prev = heap; - block->next_free = heap; - block->prev_free = heap; - - block->ofs = ofs; - block->size = size; - block->free = 1; - - return heap; -} - - -static struct mem_block * -SliceBlock(struct mem_block *p, - int startofs, int size, - int reserved, int alignment) -{ - struct mem_block *newblock; - - /* break left [p, newblock, p->next], then p = newblock */ - if (startofs > p->ofs) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs; - newblock->size = p->size - (startofs - p->ofs); - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size -= newblock->size; - p = newblock; - } - - /* break right, also [p, newblock, p->next] */ - if (size < p->size) { - newblock = CALLOC_STRUCT(mem_block); - if (!newblock) - return NULL; - newblock->ofs = startofs + size; - newblock->size = p->size - size; - newblock->free = 1; - newblock->heap = p->heap; - - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - - newblock->next_free = p->next_free; - newblock->prev_free = p; - p->next_free->prev_free = newblock; - p->next_free = newblock; - - p->size = size; - } - - /* p = middle block */ - p->free = 0; - - /* Remove p from the free list: - */ - p->next_free->prev_free = p->prev_free; - p->prev_free->next_free = p->next_free; - - p->next_free = 0; - p->prev_free = 0; - - p->reserved = reserved; - return p; -} - - -struct mem_block * -mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) -{ - struct mem_block *p; - const int mask = (1 << align2)-1; - int startofs = 0; - int endofs; - - if (!heap || align2 < 0 || size <= 0) - return NULL; - - for (p = heap->next_free; p != heap; p = p->next_free) { - assert(p->free); - - startofs = (p->ofs + mask) & ~mask; - if ( startofs < startSearch ) { - startofs = startSearch; - } - endofs = startofs+size; - if (endofs <= (p->ofs+p->size)) - break; - } - - if (p == heap) - return NULL; - - assert(p->free); - p = SliceBlock(p,startofs,size,0,mask+1); - - return p; -} - - -struct mem_block * -mmFindBlock(struct mem_block *heap, int start) -{ - struct mem_block *p; - - for (p = heap->next; p != heap; p = p->next) { - if (p->ofs == start) - return p; - } - - return NULL; -} - - -static INLINE int -Join2Blocks(struct mem_block *p) -{ - /* XXX there should be some assertions here */ - - /* NOTE: heap->free == 0 */ - - if (p->free && p->next->free) { - struct mem_block *q = p->next; - - assert(p->ofs + p->size == q->ofs); - p->size += q->size; - - p->next = q->next; - q->next->prev = p; - - q->next_free->prev_free = q->prev_free; - q->prev_free->next_free = q->next_free; - - FREE(q); - return 1; - } - return 0; -} - -int -mmFreeMem(struct mem_block *b) -{ - if (!b) - return 0; - - if (b->free) { - debug_printf("block already free\n"); - return -1; - } - if (b->reserved) { - debug_printf("block is reserved\n"); - return -1; - } - - b->free = 1; - b->next_free = b->heap->next_free; - b->prev_free = b->heap; - b->next_free->prev_free = b; - b->prev_free->next_free = b; - - Join2Blocks(b); - if (b->prev != b->heap) - Join2Blocks(b->prev); - - return 0; -} - - -void -mmDestroy(struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap) - return; - - for (p = heap->next; p != heap; ) { - struct mem_block *next = p->next; - FREE(p); - p = next; - } - - FREE(heap); -} diff --git a/src/gallium/auxiliary/rtasm/mm.h b/src/gallium/auxiliary/rtasm/mm.h deleted file mode 100644 index f469b18d3e..0000000000 --- a/src/gallium/auxiliary/rtasm/mm.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * GLX Hardware Device Driver common code - * Copyright (C) 1999 Wittawat Yamwong - * - * 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 - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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. - */ - - -/** - * Memory manager code. Primarily used by device drivers to manage texture - * heaps, etc. - */ - - -#ifndef MM_H -#define MM_H - - -struct mem_block { - struct mem_block *next, *prev; - struct mem_block *next_free, *prev_free; - struct mem_block *heap; - int ofs,size; - unsigned int free:1; - unsigned int reserved:1; -}; - - - -/** - * input: total size in bytes - * return: a heap pointer if OK, NULL if error - */ -extern struct mem_block *mmInit(int ofs, int size); - -/** - * Allocate 'size' bytes with 2^align2 bytes alignment, - * restrict the search to free memory after 'startSearch' - * depth and back buffers should be in different 4mb banks - * to get better page hits if possible - * input: size = size of block - * align2 = 2^align2 bytes alignment - * startSearch = linear offset from start of heap to begin search - * return: pointer to the allocated block, 0 if error - */ -extern struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2, - int startSearch); - -/** - * Free block starts at offset - * input: pointer to a block - * return: 0 if OK, -1 if error - */ -extern int mmFreeMem(struct mem_block *b); - -/** - * Free block starts at offset - * input: pointer to a heap, start offset - * return: pointer to a block - */ -extern struct mem_block *mmFindBlock(struct mem_block *heap, int start); - -/** - * destroy MM - */ -extern void mmDestroy(struct mem_block *mmInit); - -/** - * For debuging purpose. - */ -extern void mmDumpMemInfo(const struct mem_block *mmInit); - -#endif diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index cb13db2498..9c78fa5626 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -46,7 +46,7 @@ #include #include -#include "mm.h" +#include "util/u_mm.h" #define EXEC_HEAP_SIZE (10*1024*1024) diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index b8cb148c4f..7cc2aa44f9 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -7,7 +7,8 @@ LIBNAME = util DRIVER_SOURCES = \ p_debug.c \ p_tile.c \ - p_util.c + p_util.c \ + u_mm.c C_SOURCES = \ $(DRIVER_SOURCES) diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index b126cf44d6..4717941434 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -6,6 +6,7 @@ util = env.ConvenienceLibrary( 'p_debug.c', 'p_tile.c', 'p_util.c', + 'u_mm.c', ]) auxiliaries.insert(0, util) diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c new file mode 100644 index 0000000000..b49ae074e0 --- /dev/null +++ b/src/gallium/auxiliary/util/u_mm.c @@ -0,0 +1,283 @@ +/************************************************************************** + * + * Copyright (C) 1999 Wittawat Yamwong + * + * 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 + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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 "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" + +#include "util/u_mm.h" + + +void +mmDumpMemInfo(const struct mem_block *heap) +{ + debug_printf("Memory heap %p:\n", (void *)heap); + if (heap == 0) { + debug_printf(" heap == 0\n"); + } else { + const struct mem_block *p; + + for(p = heap->next; p != heap; p = p->next) { + debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + debug_printf("\nFree list:\n"); + + for(p = heap->next_free; p != heap; p = p->next_free) { + debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size, + p->free ? 'F':'.', + p->reserved ? 'R':'.'); + } + + } + debug_printf("End of memory blocks\n"); +} + +struct mem_block * +mmInit(int ofs, int size) +{ + struct mem_block *heap, *block; + + if (size <= 0) + return NULL; + + heap = CALLOC_STRUCT(mem_block); + if (!heap) + return NULL; + + block = CALLOC_STRUCT(mem_block); + if (!block) { + FREE(heap); + return NULL; + } + + heap->next = block; + heap->prev = block; + heap->next_free = block; + heap->prev_free = block; + + block->heap = heap; + block->next = heap; + block->prev = heap; + block->next_free = heap; + block->prev_free = heap; + + block->ofs = ofs; + block->size = size; + block->free = 1; + + return heap; +} + + +static struct mem_block * +SliceBlock(struct mem_block *p, + int startofs, int size, + int reserved, int alignment) +{ + struct mem_block *newblock; + + /* break left [p, newblock, p->next], then p = newblock */ + if (startofs > p->ofs) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size -= newblock->size; + p = newblock; + } + + /* break right, also [p, newblock, p->next] */ + if (size < p->size) { + newblock = CALLOC_STRUCT(mem_block); + if (!newblock) + return NULL; + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->heap = p->heap; + + newblock->next = p->next; + newblock->prev = p; + p->next->prev = newblock; + p->next = newblock; + + newblock->next_free = p->next_free; + newblock->prev_free = p; + p->next_free->prev_free = newblock; + p->next_free = newblock; + + p->size = size; + } + + /* p = middle block */ + p->free = 0; + + /* Remove p from the free list: + */ + p->next_free->prev_free = p->prev_free; + p->prev_free->next_free = p->next_free; + + p->next_free = 0; + p->prev_free = 0; + + p->reserved = reserved; + return p; +} + + +struct mem_block * +mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) +{ + struct mem_block *p; + const int mask = (1 << align2)-1; + int startofs = 0; + int endofs; + + if (!heap || align2 < 0 || size <= 0) + return NULL; + + for (p = heap->next_free; p != heap; p = p->next_free) { + assert(p->free); + + startofs = (p->ofs + mask) & ~mask; + if ( startofs < startSearch ) { + startofs = startSearch; + } + endofs = startofs+size; + if (endofs <= (p->ofs+p->size)) + break; + } + + if (p == heap) + return NULL; + + assert(p->free); + p = SliceBlock(p,startofs,size,0,mask+1); + + return p; +} + + +struct mem_block * +mmFindBlock(struct mem_block *heap, int start) +{ + struct mem_block *p; + + for (p = heap->next; p != heap; p = p->next) { + if (p->ofs == start) + return p; + } + + return NULL; +} + + +static INLINE int +Join2Blocks(struct mem_block *p) +{ + /* XXX there should be some assertions here */ + + /* NOTE: heap->free == 0 */ + + if (p->free && p->next->free) { + struct mem_block *q = p->next; + + assert(p->ofs + p->size == q->ofs); + p->size += q->size; + + p->next = q->next; + q->next->prev = p; + + q->next_free->prev_free = q->prev_free; + q->prev_free->next_free = q->next_free; + + FREE(q); + return 1; + } + return 0; +} + +int +mmFreeMem(struct mem_block *b) +{ + if (!b) + return 0; + + if (b->free) { + debug_printf("block already free\n"); + return -1; + } + if (b->reserved) { + debug_printf("block is reserved\n"); + return -1; + } + + b->free = 1; + b->next_free = b->heap->next_free; + b->prev_free = b->heap; + b->next_free->prev_free = b; + b->prev_free->next_free = b; + + Join2Blocks(b); + if (b->prev != b->heap) + Join2Blocks(b->prev); + + return 0; +} + + +void +mmDestroy(struct mem_block *heap) +{ + struct mem_block *p; + + if (!heap) + return; + + for (p = heap->next; p != heap; ) { + struct mem_block *next = p->next; + FREE(p); + p = next; + } + + FREE(heap); +} diff --git a/src/gallium/auxiliary/util/u_mm.h b/src/gallium/auxiliary/util/u_mm.h new file mode 100644 index 0000000000..b226b101cb --- /dev/null +++ b/src/gallium/auxiliary/util/u_mm.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * Copyright (C) 1999 Wittawat Yamwong + * + * 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 + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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 + * Memory manager code. Primarily used by device drivers to manage texture + * heaps, etc. + */ + + +#ifndef _U_MM_H_ +#define _U_MM_H_ + + +struct mem_block { + struct mem_block *next, *prev; + struct mem_block *next_free, *prev_free; + struct mem_block *heap; + int ofs,size; + unsigned int free:1; + unsigned int reserved:1; +}; + + + +/** + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +extern struct mem_block *mmInit(int ofs, int size); + +/** + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +extern struct mem_block *mmAllocMem(struct mem_block *heap, int size, int align2, + int startSearch); + +/** + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +extern int mmFreeMem(struct mem_block *b); + +/** + * Free block starts at offset + * input: pointer to a heap, start offset + * return: pointer to a block + */ +extern struct mem_block *mmFindBlock(struct mem_block *heap, int start); + +/** + * destroy MM + */ +extern void mmDestroy(struct mem_block *mmInit); + +/** + * For debuging purpose. + */ +extern void mmDumpMemInfo(const struct mem_block *mmInit); + +#endif -- cgit v1.2.3 From f430d95a36d55141cd9ef911aab70364ce4a4108 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 12:52:28 +0900 Subject: Use gallium's rtasm module. --- src/gallium/auxiliary/draw/draw_private.h | 2 +- src/gallium/auxiliary/draw/draw_vf.c | 10 +++------- src/gallium/auxiliary/draw/draw_vf_sse.c | 2 +- src/gallium/auxiliary/draw/draw_vs_sse.c | 2 +- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- src/gallium/drivers/softpipe/sp_fs_sse.c | 2 +- src/mesa/state_tracker/st_program.h | 1 - 7 files changed, 8 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index dd75f9aefc..6c7e860861 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -44,7 +44,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_exec.h" diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c index dc3a5ecd21..901ff20a7e 100644 --- a/src/gallium/auxiliary/draw/draw_vf.c +++ b/src/gallium/auxiliary/draw/draw_vf.c @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_util.h" +#include "rtasm/rtasm_execmem.h" #include "draw_vf.h" @@ -37,11 +38,6 @@ #define DRAW_VF_DBG 0 -/* TODO: remove this */ -extern void -_mesa_exec_free( void *addr ); - - static boolean match_fastpath( struct draw_vertex_fetch *vf, const struct draw_vf_fastpath *fp) { @@ -414,12 +410,12 @@ void draw_vf_destroy( struct draw_vertex_fetch *vf ) FREE(fp->attr); /* KW: At the moment, fp->func is constrained to be allocated by - * _mesa_exec_alloc(), as the hardwired fastpaths in + * rtasm_exec_alloc(), as the hardwired fastpaths in * t_vertex_generic.c are handled specially. It would be nice * to unify them, but this probably won't change until this * module gets another overhaul. */ - //_mesa_exec_free((void *) fp->func); + //rtasm_exec_free((void *) fp->func); FREE(fp); } diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c index 1ad2ae756d..1e889deeea 100644 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ b/src/gallium/auxiliary/draw/draw_vf_sse.c @@ -35,7 +35,7 @@ #if defined(USE_SSE_ASM) -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" #include "x86/common_x86_asm.h" diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 27bc66812c..11ef0c503d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -41,7 +41,7 @@ #include "draw_private.h" #include "draw_context.h" -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_sse2.h" diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 62c6a69c63..29a7f842ed 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -32,7 +32,7 @@ #include "tgsi_exec.h" #include "tgsi_sse2.h" -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" #if defined(__i386__) || defined(__386__) diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index d90066e025..b18772f4e6 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -42,7 +42,7 @@ #if defined(__i386__) || defined(__386__) -#include "x86/rtasm/x86sse.h" +#include "rtasm/rtasm_x86sse.h" /* Surely this should be defined somewhere in a tgsi header: */ diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index ea1dde4a7a..25cf3e94a8 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -36,7 +36,6 @@ #include "mtypes.h" #include "pipe/p_shader_tokens.h" -#include "x86/rtasm/x86sse.h" #define ST_MAX_SHADER_TOKENS 1024 -- cgit v1.2.3 From 90b2beb661f630966788a6e909dc759c99e38973 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 13:27:13 +0900 Subject: Simplify makefile boilerplate code. Don't define ASM_SOURCES variable globally -- reserve that variable to be defined locally by makefiles, together with C_SOURCES and CPP_SOURCES. --- configs/beos | 4 ++-- configs/default | 2 +- configs/freebsd-dri | 2 +- configs/freebsd-dri-amd64 | 4 ++-- configs/freebsd-dri-x86 | 4 ++-- configs/linux-directfb | 4 ++-- configs/linux-dri | 2 +- configs/linux-dri-ppc | 2 +- configs/linux-dri-x86 | 4 ++-- configs/linux-dri-x86-64 | 4 ++-- configs/linux-dri-xcb | 2 +- configs/linux-icc | 4 ++-- configs/linux-icc-static | 4 ++-- configs/linux-indirect | 2 +- configs/linux-solo | 2 +- configs/linux-solo-x86 | 4 ++-- configs/linux-sparc | 4 ++-- configs/linux-x86 | 4 ++-- configs/linux-x86-64 | 4 ++-- configs/linux-x86-glide | 4 ++-- configs/sunos5-gcc | 4 ++-- src/gallium/auxiliary/cso_cache/Makefile | 7 +------ src/gallium/auxiliary/draw/Makefile | 7 +------ src/gallium/auxiliary/pipebuffer/Makefile | 8 +------- src/gallium/auxiliary/rtasm/Makefile | 8 +------- src/gallium/auxiliary/tgsi/Makefile | 8 +------- src/gallium/auxiliary/util/Makefile | 8 +------- src/gallium/drivers/failover/Makefile | 9 +-------- src/gallium/drivers/i915simple/Makefile | 9 +-------- src/gallium/drivers/i965simple/Makefile | 25 +++++++------------------ src/gallium/drivers/softpipe/Makefile | 9 +-------- src/gallium/winsys/dri/Makefile.template | 5 +++-- src/glx/x11/Makefile | 6 +++--- src/mesa/sources | 6 +++--- 34 files changed, 60 insertions(+), 125 deletions(-) (limited to 'src') diff --git a/configs/beos b/configs/beos index 2b74af739d..c6e972789a 100644 --- a/configs/beos +++ b/configs/beos @@ -26,8 +26,8 @@ ifeq ($(CPU), x86) -DUSE_3DNOW_ASM \ -DUSE_SSE_ASM - ASM_SOURCES = $(X86_SOURCES) - ASM_API = $(X86_API) + MESA_ASM_SOURCES = $(X86_SOURCES) + GLAPI_ASM_SOURCES = $(X86_API) CC = gcc CXX = g++ diff --git a/configs/default b/configs/default index c9be5ec3e3..48ddd29282 100644 --- a/configs/default +++ b/configs/default @@ -51,7 +51,7 @@ OSMESA_LIB_NAME = lib$(OSMESA_LIB).so # Optional assembly language optimization files for libGL -ASM_SOURCES = +MESA_ASM_SOURCES = # GLw widget sources (Append "GLwMDrawA.c" here and add -lXm to GLW_LIB_DEPS in # order to build the Motif widget too) diff --git a/configs/freebsd-dri b/configs/freebsd-dri index 67d253b869..6fc1abbc80 100644 --- a/configs/freebsd-dri +++ b/configs/freebsd-dri @@ -22,7 +22,7 @@ CFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) -Wmissing-prototypes -std=c99 - CXXFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) $(DEFINES) -Wall -ansi -pedantic $(ASM_FLAGS) $(X11_INCLUDES) -ASM_SOURCES = +MESA_ASM_SOURCES = # Library/program dependencies LIBDRM_CFLAGS = `pkg-config --cflags libdrm` diff --git a/configs/freebsd-dri-amd64 b/configs/freebsd-dri-amd64 index 39341b9701..bb6c361398 100644 --- a/configs/freebsd-dri-amd64 +++ b/configs/freebsd-dri-amd64 @@ -6,5 +6,5 @@ include $(TOP)/configs/freebsd-dri CONFIG_NAME = freebsd-dri-x86-64 ASM_FLAGS = -DUSE_X86_64_ASM -ASM_SOURCES = $(X86-64_SOURCES) -ASM_API = $(X86-64_API) +MESA_ASM_SOURCES = $(X86-64_SOURCES) +GLAPI_ASM_SOURCES = $(X86-64_API) diff --git a/configs/freebsd-dri-x86 b/configs/freebsd-dri-x86 index af0d27ff47..9475437fc5 100644 --- a/configs/freebsd-dri-x86 +++ b/configs/freebsd-dri-x86 @@ -9,5 +9,5 @@ CONFIG_NAME = freebsd-dri-x86 PIC_FLAGS = ASM_FLAGS = -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM -ASM_SOURCES = $(X86_SOURCES) -ASM_API = $(X86_API) +MESA_ASM_SOURCES = $(X86_SOURCES) +GLAPI_ASM_SOURCES = $(X86_API) diff --git a/configs/linux-directfb b/configs/linux-directfb index dff27f7850..2ed94fe275 100644 --- a/configs/linux-directfb +++ b/configs/linux-directfb @@ -17,8 +17,8 @@ HAVE_X86 = $(shell uname -m | grep 'i[3-6]86' >/dev/null && echo yes) ifeq ($(HAVE_X86), yes) CFLAGS += -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM CXXFLAGS += -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM - ASM_SOURCES = $(X86_SOURCES) - ASM_API = $(X86_API) + MESA_ASM_SOURCES = $(X86_SOURCES) + GLAPI_ASM_SOURCES = $(X86_API) endif # Directories diff --git a/configs/linux-dri b/configs/linux-dri index c45b600013..67e60cbd4c 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -33,7 +33,7 @@ CFLAGS = -Wall -Wmissing-prototypes -std=c99 -ffast-math \ CXXFLAGS = -Wall $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) -ASM_SOURCES = +MESA_ASM_SOURCES = # Library/program dependencies EXTRA_LIB_PATH=-L/usr/X11R6/lib diff --git a/configs/linux-dri-ppc b/configs/linux-dri-ppc index fb87688065..a3a3ca83cb 100644 --- a/configs/linux-dri-ppc +++ b/configs/linux-dri-ppc @@ -9,7 +9,7 @@ OPT_FLAGS = -Os -mcpu=603 PIC_FLAGS = -fPIC ASM_FLAGS = -DUSE_PPC_ASM -DUSE_VMX_ASM -ASM_SOURCES = $(PPC_SOURCES) +MESA_ASM_SOURCES = $(PPC_SOURCES) # Build only the drivers for cards that exist on PowerPC. At some point MGA # will be added, but not yet. diff --git a/configs/linux-dri-x86 b/configs/linux-dri-x86 index b196004e58..ec8242dd68 100644 --- a/configs/linux-dri-x86 +++ b/configs/linux-dri-x86 @@ -12,6 +12,6 @@ PIC_FLAGS = ARCH_FLAGS = -m32 ASM_FLAGS = -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM -ASM_SOURCES = $(X86_SOURCES) -ASM_API = $(X86_API) +MESA_ASM_SOURCES = $(X86_SOURCES) +GLAPI_ASM_SOURCES = $(X86_API) diff --git a/configs/linux-dri-x86-64 b/configs/linux-dri-x86-64 index 821ab3e336..bb56de375a 100644 --- a/configs/linux-dri-x86-64 +++ b/configs/linux-dri-x86-64 @@ -8,8 +8,8 @@ CONFIG_NAME = linux-dri-x86-64 ARCH_FLAGS = -m64 ASM_FLAGS = -DUSE_X86_64_ASM -ASM_SOURCES = $(X86-64_SOURCES) -ASM_API = $(X86-64_API) +MESA_ASM_SOURCES = $(X86-64_SOURCES) +GLAPI_ASM_SOURCES = $(X86-64_API) LIB_DIR = lib64 diff --git a/configs/linux-dri-xcb b/configs/linux-dri-xcb index ea4bdf1864..fbf9b9b268 100644 --- a/configs/linux-dri-xcb +++ b/configs/linux-dri-xcb @@ -33,7 +33,7 @@ CFLAGS = -Wall -Wmissing-prototypes $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) \ CXXFLAGS = -Wall $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) -ASM_SOURCES = +MESA_ASM_SOURCES = # Library/program dependencies EXTRA_LIB_PATH=$(shell pkg-config --libs-only-L x11) diff --git a/configs/linux-icc b/configs/linux-icc index 978a45af70..d90a1dab3d 100644 --- a/configs/linux-icc +++ b/configs/linux-icc @@ -16,7 +16,7 @@ GL_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXext -lm -lpthread GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) -L/usr/X11R6/lib -lX11 -lXmu -lXt -lXi -lm APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -lm -ASM_SOURCES = $(X86_SOURCES) -ASM_API = $(X86_API) +MESA_ASM_SOURCES = $(X86_SOURCES) +GLAPI_ASM_SOURCES = $(X86_API) diff --git a/configs/linux-icc-static b/configs/linux-icc-static index 0c957568c2..384db3bfe4 100644 --- a/configs/linux-icc-static +++ b/configs/linux-icc-static @@ -23,5 +23,5 @@ GL_LIB_DEPS = GLUT_LIB_DEPS = APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -L/usr/X11R6/lib -lX11 -lXmu -lXt -lXi -lm -lpthread -lcxa -lunwind -ASM_SOURCES = $(X86_SOURCES) -ASM_API = $(X86_API) +MESA_ASM_SOURCES = $(X86_SOURCES) +GLAPI_ASM_SOURCES = $(X86_API) diff --git a/configs/linux-indirect b/configs/linux-indirect index bd33345ed7..0c4805ea87 100644 --- a/configs/linux-indirect +++ b/configs/linux-indirect @@ -34,7 +34,7 @@ CFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) \ CXXFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) -ASM_SOURCES = +MESA_ASM_SOURCES = # Library/program dependencies EXTRA_LIB_PATH=-L/usr/X11R6/lib diff --git a/configs/linux-solo b/configs/linux-solo index d49b972228..3145e12775 100644 --- a/configs/linux-solo +++ b/configs/linux-solo @@ -33,7 +33,7 @@ CFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) \ CXXFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) -ASM_SOURCES = +MESA_ASM_SOURCES = # Library/program dependencies DRI_LIB_DEPS = -lm -lpthread -lexpat -ldl -L$(TOP)/$(LIB_DIR) $(PCIACCESS_LIB) diff --git a/configs/linux-solo-x86 b/configs/linux-solo-x86 index 13cab37658..5f5aa09c82 100644 --- a/configs/linux-solo-x86 +++ b/configs/linux-solo-x86 @@ -9,5 +9,5 @@ CONFIG_NAME = linux-solo-x86 PIC_FLAGS = ASM_FLAGS = -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM -ASM_SOURCES = $(X86_SOURCES) -ASM_API = $(X86_API) +MESA_ASM_SOURCES = $(X86_SOURCES) +GLAPI_ASM_SOURCES = $(X86_API) diff --git a/configs/linux-sparc b/configs/linux-sparc index 9925afc19b..346d438c28 100644 --- a/configs/linux-sparc +++ b/configs/linux-sparc @@ -5,5 +5,5 @@ include $(TOP)/configs/linux CONFIG_NAME = linux-sparc #ASM_FLAGS = -DUSE_SPARC_ASM -#ASM_SOURCES = $(SPARC_SOURCES) -#ASM_API = $(SPARC_API) +#MESA_ASM_SOURCES = $(SPARC_SOURCES) +#GLAPI_ASM_SOURCES = $(SPARC_API) diff --git a/configs/linux-x86 b/configs/linux-x86 index 18fa06101d..a4cf4e8d62 100644 --- a/configs/linux-x86 +++ b/configs/linux-x86 @@ -5,5 +5,5 @@ include $(TOP)/configs/linux CONFIG_NAME = linux-x86 ASM_FLAGS = -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM -ASM_SOURCES = $(X86_SOURCES) -ASM_API = $(X86_API) +MESA_ASM_SOURCES = $(X86_SOURCES) +GLAPI_ASM_SOURCES = $(X86_API) diff --git a/configs/linux-x86-64 b/configs/linux-x86-64 index 67c0391836..c2441e09d0 100644 --- a/configs/linux-x86-64 +++ b/configs/linux-x86-64 @@ -6,8 +6,8 @@ CONFIG_NAME = linux-x86-64 ARCH_FLAGS = -m64 -ASM_SOURCES = $(X86-64_SOURCES) -ASM_API = $(X86-64_API) +MESA_ASM_SOURCES = $(X86-64_SOURCES) +GLAPI_ASM_SOURCES = $(X86-64_API) ASM_FLAGS = -DUSE_X86_64_ASM LIB_DIR = lib64 diff --git a/configs/linux-x86-glide b/configs/linux-x86-glide index f2f8aeea60..b963fbdc66 100644 --- a/configs/linux-x86-glide +++ b/configs/linux-x86-glide @@ -15,8 +15,8 @@ CXXFLAGS = -Wall -O3 -ansi -pedantic -fPIC -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199 GLUT_CFLAGS = -fexceptions -ASM_SOURCES = $(X86_SOURCES) -ASM_API = $(X86_API) +MESA_ASM_SOURCES = $(X86_SOURCES) +GLAPI_ASM_SOURCES = $(X86_API) # Library/program dependencies GL_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXext -L/usr/local/glide/lib -lglide3x -lm -lpthread diff --git a/configs/sunos5-gcc b/configs/sunos5-gcc index 77b293c545..3fa13d0496 100644 --- a/configs/sunos5-gcc +++ b/configs/sunos5-gcc @@ -16,8 +16,8 @@ ARCH_FLAGS ?= DEFINES = -D_REENTRANT -DUSE_XSHM -ASM_SOURCES = $(SPARC_SOURCES) -ASM_API = $(SPARC_API) +MESA_ASM_SOURCES = $(SPARC_SOURCES) +GLAPI_ASM_SOURCES = $(SPARC_API) ASM_FLAGS = -DUSE_SPARC_ASM CFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) \ diff --git a/src/gallium/auxiliary/cso_cache/Makefile b/src/gallium/auxiliary/cso_cache/Makefile index 8248b097fd..3e49266163 100644 --- a/src/gallium/auxiliary/cso_cache/Makefile +++ b/src/gallium/auxiliary/cso_cache/Makefile @@ -3,15 +3,10 @@ include $(TOP)/configs/current LIBNAME = cso_cache -DRIVER_SOURCES = \ +C_SOURCES = \ cso_cache.c \ cso_hash.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index c8000cbe9c..1ee9eca0ca 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -3,7 +3,7 @@ include $(TOP)/configs/current LIBNAME = draw -DRIVER_SOURCES = \ +C_SOURCES = \ draw_aaline.c \ draw_clip.c \ draw_vs_exec.c \ @@ -29,11 +29,6 @@ DRIVER_SOURCES = \ draw_vf_sse.c \ draw_wide_prims.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index 588629e870..a9fa518c67 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -1,10 +1,9 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = pipebuffer -DRIVER_SOURCES = \ +C_SOURCES = \ pb_buffer_fenced.c \ pb_buffer_malloc.c \ pb_bufmgr_fenced.c \ @@ -12,11 +11,6 @@ DRIVER_SOURCES = \ pb_bufmgr_pool.c \ pb_winsys.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index edfae2a204..bc339d2aa6 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -1,18 +1,12 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = rtasm -DRIVER_SOURCES = \ +C_SOURCES = \ rtasm_execmem.c \ rtasm_x86sse.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile index 8bb62b2a0a..71f64b747c 100644 --- a/src/gallium/auxiliary/tgsi/Makefile +++ b/src/gallium/auxiliary/tgsi/Makefile @@ -1,10 +1,9 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = tgsi -DRIVER_SOURCES = \ +C_SOURCES = \ exec/tgsi_exec.c \ exec/tgsi_sse2.c \ util/tgsi_build.c \ @@ -13,11 +12,6 @@ DRIVER_SOURCES = \ util/tgsi_transform.c \ util/tgsi_util.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile index 7cc2aa44f9..906a46d6b4 100644 --- a/src/gallium/auxiliary/util/Makefile +++ b/src/gallium/auxiliary/util/Makefile @@ -1,20 +1,14 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = util -DRIVER_SOURCES = \ +C_SOURCES = \ p_debug.c \ p_tile.c \ p_util.c \ u_mm.c -C_SOURCES = \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/failover/Makefile b/src/gallium/drivers/failover/Makefile index 14389bd055..f08b8df07a 100644 --- a/src/gallium/drivers/failover/Makefile +++ b/src/gallium/drivers/failover/Makefile @@ -1,20 +1,13 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = failover -DRIVER_SOURCES = \ +C_SOURCES = \ fo_state.c \ fo_state_emit.c \ fo_context.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile index ee22ba86f9..2a75f5d57c 100644 --- a/src/gallium/drivers/i915simple/Makefile +++ b/src/gallium/drivers/i915simple/Makefile @@ -1,10 +1,9 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = i915simple -DRIVER_SOURCES = \ +C_SOURCES = \ i915_blit.c \ i915_clear.c \ i915_flush.c \ @@ -26,12 +25,6 @@ DRIVER_SOURCES = \ i915_fpc_translate.c \ i915_surface.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/i965simple/Makefile b/src/gallium/drivers/i965simple/Makefile index 1dec1f9749..cc8580836c 100644 --- a/src/gallium/drivers/i965simple/Makefile +++ b/src/gallium/drivers/i965simple/Makefile @@ -1,14 +1,13 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = i965simple -DRIVER_SOURCES = \ - brw_blit.c \ - brw_flush.c \ - brw_strings.c \ - brw_surface.c \ +C_SOURCES = \ + brw_blit.c \ + brw_flush.c \ + brw_strings.c \ + brw_surface.c \ brw_cc.c \ brw_clip.c \ brw_clip_line.c \ @@ -31,8 +30,8 @@ DRIVER_SOURCES = \ brw_sf.c \ brw_sf_emit.c \ brw_sf_state.c \ - brw_shader_info.c \ - brw_state.c \ + brw_shader_info.c \ + brw_state.c \ brw_state_batch.c \ brw_state_cache.c \ brw_state_pool.c \ @@ -51,16 +50,6 @@ DRIVER_SOURCES = \ brw_wm_state.c \ brw_wm_surface_state.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(COMMON_BM_SOURCES) \ - $(MINIGLX_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -DRIVER_DEFINES = -I. - include ../../Makefile.template symlinks: diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index 5479daf8ea..539ffb77f5 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -1,10 +1,9 @@ - TOP = ../../../.. include $(TOP)/configs/current LIBNAME = softpipe -DRIVER_SOURCES = \ +C_SOURCES = \ sp_fs_exec.c \ sp_fs_sse.c \ sp_fs_llvm.c \ @@ -41,12 +40,6 @@ DRIVER_SOURCES = \ sp_tile_cache.c \ sp_surface.c -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - include ../../Makefile.template symlinks: diff --git a/src/gallium/winsys/dri/Makefile.template b/src/gallium/winsys/dri/Makefile.template index 65a93bd53e..3bc1fdd4d4 100644 --- a/src/gallium/winsys/dri/Makefile.template +++ b/src/gallium/winsys/dri/Makefile.template @@ -25,8 +25,9 @@ WINOBJ= WINLIB= INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) -OBJECTS = $(C_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) +OBJECTS = \ + $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) else # miniglx diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile index 5f74fcff06..b404727f08 100644 --- a/src/glx/x11/Makefile +++ b/src/glx/x11/Makefile @@ -35,7 +35,7 @@ SOURCES = \ include $(TOP)/src/mesa/sources -MESA_ASM_API = $(addprefix $(TOP)/src/mesa/, $(ASM_API)) +MESA_GLAPI_ASM_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_ASM_SOURCES)) MESA_GLAPI_SOURCES = $(addprefix $(TOP)/src/mesa/, $(GLAPI_SOURCES)) MESA_GLAPI_OBJECTS = $(addprefix $(TOP)/src/mesa/, $(GLAPI_OBJECTS)) @@ -70,11 +70,11 @@ $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) Makefile -install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS) -depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_ASM_API) Makefile +depend: $(SOURCES) $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) Makefile rm -f depend touch depend $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(SOURCES) \ - $(MESA_GLAPI_SOURCES) $(MESA_ASM_API) + $(MESA_GLAPI_SOURCES) $(MESA_GLAPI_ASM_SOURCES) # Emacs tags diff --git a/src/mesa/sources b/src/mesa/sources index 0d185fd5f3..9e56694893 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -320,7 +320,7 @@ FBDEV_DRIVER_SOURCES = \ ALL_SOURCES = \ $(GLAPI_SOURCES) \ $(SOLO_SOURCES) \ - $(ASM_SOURCES) \ + $(MESA_ASM_SOURCES) \ $(COMMON_DRIVER_SOURCES)\ $(X11_DRIVER_SOURCES) \ $(FBDEV_DRIVER_SOURCES) \ @@ -353,11 +353,11 @@ CORE_SOURCES = \ SOLO_OBJECTS = \ $(SOLO_SOURCES:.c=.o) \ - $(ASM_SOURCES:.S=.o) + $(MESA_ASM_SOURCES:.S=.o) GLAPI_OBJECTS = \ $(GLAPI_SOURCES:.c=.o) \ - $(ASM_API:.S=.o) + $(GLAPI_ASM_SOURCES:.S=.o) CORE_OBJECTS = $(SOLO_OBJECTS) $(GLAPI_OBJECTS) -- cgit v1.2.3 From b0eef0dc2557febea7d425fee1f9c2da382898a6 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 13:41:38 +0900 Subject: Add run-time cpu capabilities detection stubs. --- src/gallium/auxiliary/draw/draw_vf_sse.c | 6 ++-- src/gallium/auxiliary/rtasm/Makefile | 1 + src/gallium/auxiliary/rtasm/SConscript | 1 + src/gallium/auxiliary/rtasm/rtasm_cpu.c | 50 ++++++++++++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_cpu.h | 42 +++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 src/gallium/auxiliary/rtasm/rtasm_cpu.c create mode 100644 src/gallium/auxiliary/rtasm/rtasm_cpu.h (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c index 1e889deeea..6076f9849d 100644 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ b/src/gallium/auxiliary/draw/draw_vf_sse.c @@ -35,8 +35,8 @@ #if defined(USE_SSE_ASM) +#include "rtasm/rtasm_cpu.h" #include "rtasm/rtasm_x86sse.h" -#include "x86/common_x86_asm.h" #define X 0 @@ -576,7 +576,7 @@ void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) { struct x86_program p; - if (!cpu_has_xmm) { + if (!rtasm_cpu_has_sse()) { vf->codegen_emit = NULL; return; } @@ -586,7 +586,7 @@ void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) p.vf = vf; p.inputs_safe = 0; /* for now */ p.outputs_safe = 1; /* for now */ - p.have_sse2 = cpu_has_xmm2; + p.have_sse2 = rtasm_cpu_has_sse2(); p.identity = x86_make_reg(file_XMM, 6); p.chan0 = x86_make_reg(file_XMM, 7); diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index bc339d2aa6..9b972f8f86 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = rtasm C_SOURCES = \ + rtasm_cpu.c \ rtasm_execmem.c \ rtasm_x86sse.c diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index 6eca1fe4c0..ac41a4f212 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -3,6 +3,7 @@ Import('*') rtasm = env.ConvenienceLibrary( target = 'rtasm', source = [ + 'rtasm_cpu.c', 'rtasm_execmem.c', 'rtasm_x86sse.c' ]) diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c new file mode 100644 index 0000000000..eb3359750b --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "rtasm_cpu.h" + + +int rtasm_cpu_has_sse(void) +{ + /* FIXME: actually detect this at run-time */ +#if defined(__i386__) || defined(__386__) + return 1; +#else + return 0; +#endif +} + +int rtasm_cpu_has_sse2(void) +{ + /* FIXME: actually detect this at run-time */ +#if defined(__i386__) || defined(__386__) + return 1; +#else + return 0; +#endif +} diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.h b/src/gallium/auxiliary/rtasm/rtasm_cpu.h new file mode 100644 index 0000000000..ebc71634fd --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.h @@ -0,0 +1,42 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Runtime detection of CPU capabilities. + */ + +#ifndef _RTASM_CPU_H_ +#define _RTASM_CPU_H_ + + +int rtasm_cpu_has_sse(void); + +int rtasm_cpu_has_sse2(void); + + +#endif /* _RTASM_CPU_H_ */ -- cgit v1.2.3 From 5d78212d752e021555356bbb9cc5993ad6d9e847 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 14:00:16 +0900 Subject: Bring in ppc spe rtasm into gallium's rtasm module. Moving files since these are not being used outside gallium. --- src/gallium/auxiliary/rtasm/Makefile | 3 +- src/gallium/auxiliary/rtasm/SConscript | 3 +- src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c | 386 +++++++++++++++++++++++ src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h | 314 ++++++++++++++++++ src/gallium/drivers/cell/ppu/cell_context.h | 2 +- src/gallium/drivers/cell/ppu/cell_vertex_fetch.c | 2 +- src/mesa/ppc/rtasm/spe_asm.c | 385 ---------------------- src/mesa/ppc/rtasm/spe_asm.h | 314 ------------------ src/mesa/sources | 1 - 9 files changed, 706 insertions(+), 704 deletions(-) create mode 100644 src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c create mode 100644 src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h delete mode 100644 src/mesa/ppc/rtasm/spe_asm.c delete mode 100644 src/mesa/ppc/rtasm/spe_asm.h (limited to 'src') diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile index 9b972f8f86..39b8a4dbd7 100644 --- a/src/gallium/auxiliary/rtasm/Makefile +++ b/src/gallium/auxiliary/rtasm/Makefile @@ -6,7 +6,8 @@ LIBNAME = rtasm C_SOURCES = \ rtasm_cpu.c \ rtasm_execmem.c \ - rtasm_x86sse.c + rtasm_x86sse.c \ + rtasm_ppc_spe.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index ac41a4f212..8ea25922aa 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -5,7 +5,8 @@ rtasm = env.ConvenienceLibrary( source = [ 'rtasm_cpu.c', 'rtasm_execmem.c', - 'rtasm_x86sse.c' + 'rtasm_x86sse.c', + 'rtasm_ppc_spe.c', ]) auxiliaries.insert(0, rtasm) diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c new file mode 100644 index 0000000000..95a2d6fcbb --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c @@ -0,0 +1,386 @@ +/* + * (C) Copyright IBM Corporation 2008 + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file + * Real-time assembly generation interface for Cell B.E. SPEs. + * + * \author Ian Romanick + */ + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "rtasm_ppc_spe.h" + +#ifdef GALLIUM_CELL +/** + * SPE instruction types + * + * There are 6 primary instruction encodings used on the Cell's SPEs. Each of + * the following unions encodes one type. + * + * \bug + * If, at some point, we start generating SPE code from a little-endian host + * these unions will not work. + */ +/*@{*/ +/** + * Encode one output register with two input registers + */ +union spe_inst_RR { + uint32_t bits; + struct { + unsigned op:11; + unsigned rB:7; + unsigned rA:7; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with three input registers + */ +union spe_inst_RRR { + uint32_t bits; + struct { + unsigned op:4; + unsigned rT:7; + unsigned rB:7; + unsigned rA:7; + unsigned rC:7; + } inst; +}; + + +/** + * Encode one output register with one input reg. and a 7-bit signed immed + */ +union spe_inst_RI7 { + uint32_t bits; + struct { + unsigned op:11; + unsigned i7:7; + unsigned rA:7; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with one input reg. and an 8-bit signed immed + */ +union spe_inst_RI8 { + uint32_t bits; + struct { + unsigned op:10; + unsigned i8:8; + unsigned rA:7; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with one input reg. and a 10-bit signed immed + */ +union spe_inst_RI10 { + uint32_t bits; + struct { + unsigned op:8; + unsigned i10:10; + unsigned rA:7; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with a 16-bit signed immediate + */ +union spe_inst_RI16 { + uint32_t bits; + struct { + unsigned op:9; + unsigned i16:16; + unsigned rT:7; + } inst; +}; + + +/** + * Encode one output register with a 18-bit signed immediate + */ +union spe_inst_RI18 { + uint32_t bits; + struct { + unsigned op:7; + unsigned i18:18; + unsigned rT:7; + } inst; +}; +/*@}*/ + + +static void emit_RR(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, unsigned rB) +{ + union spe_inst_RR inst; + inst.inst.op = op; + inst.inst.rB = rB; + inst.inst.rA = rA; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + +static void emit_RRR(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, unsigned rB, unsigned rC) +{ + union spe_inst_RRR inst; + inst.inst.op = op; + inst.inst.rT = rT; + inst.inst.rB = rB; + inst.inst.rA = rA; + inst.inst.rC = rC; + *p->csr = inst.bits; + p->csr++; +} + + +static void emit_RI7(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, int imm) +{ + union spe_inst_RI7 inst; + inst.inst.op = op; + inst.inst.i7 = imm; + inst.inst.rA = rA; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + + +static void emit_RI8(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, int imm) +{ + union spe_inst_RI8 inst; + inst.inst.op = op; + inst.inst.i8 = imm; + inst.inst.rA = rA; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + + +static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT, + unsigned rA, int imm) +{ + union spe_inst_RI10 inst; + inst.inst.op = op; + inst.inst.i10 = imm; + inst.inst.rA = rA; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + +static void emit_RI16(struct spe_function *p, unsigned op, unsigned rT, + int imm) +{ + union spe_inst_RI16 inst; + inst.inst.op = op; + inst.inst.i16 = imm; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + +static void emit_RI18(struct spe_function *p, unsigned op, unsigned rT, + int imm) +{ + union spe_inst_RI18 inst; + inst.inst.op = op; + inst.inst.i18 = imm; + inst.inst.rT = rT; + *p->csr = inst.bits; + p->csr++; +} + + + + +#define EMIT_(_name, _op) \ +void _name (struct spe_function *p, unsigned rT) \ +{ \ + emit_RR(p, _op, rT, 0, 0); \ +} + +#define EMIT_R(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA) \ +{ \ + emit_RR(p, _op, rT, rA, 0); \ +} + +#define EMIT_RR(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB) \ +{ \ + emit_RR(p, _op, rT, rA, rB); \ +} + +#define EMIT_RRR(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB, unsigned rC) \ +{ \ + emit_RRR(p, _op, rT, rA, rB, rC); \ +} + +#define EMIT_RI7(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ +{ \ + emit_RI7(p, _op, rT, rA, imm); \ +} + +#define EMIT_RI8(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ +{ \ + emit_RI8(p, _op, rT, rA, 155 - imm); \ +} + +#define EMIT_RI10(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ +{ \ + emit_RI10(p, _op, rT, rA, imm); \ +} + +#define EMIT_RI16(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, int imm) \ +{ \ + emit_RI16(p, _op, rT, imm); \ +} + +#define EMIT_RI18(_name, _op) \ +void _name (struct spe_function *p, unsigned rT, int imm) \ +{ \ + emit_RI18(p, _op, rT, imm); \ +} + +#define EMIT_I16(_name, _op) \ +void _name (struct spe_function *p, int imm) \ +{ \ + emit_RI16(p, _op, 0, imm); \ +} + +#include "rtasm_ppc_spe.h" + + +/* + */ +void spe_init_func(struct spe_function *p, unsigned code_size) +{ + p->store = align_malloc(code_size, 16); + p->csr = p->store; +} + + +void spe_release_func(struct spe_function *p) +{ + align_free(p->store); + p->store = NULL; + p->csr = NULL; +} + + +void spe_bi(struct spe_function *p, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x1a8, 0, rA, (d << 5) | (e << 4)); +} + +void spe_iret(struct spe_function *p, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x1aa, 0, rA, (d << 5) | (e << 4)); +} + +void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, int d, + int e) +{ + emit_RI7(p, 0x1ab, rT, rA, (d << 5) | (e << 4)); +} + +void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, int d, + int e) +{ + emit_RI7(p, 0x1a9, rT, rA, (d << 5) | (e << 4)); +} + +void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, int d, + int e) +{ + emit_RI7(p, 0x128, rT, rA, (d << 5) | (e << 4)); +} + +void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x129, rT, rA, (d << 5) | (e << 4)); +} + +void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x12a, rT, rA, (d << 5) | (e << 4)); +} + +void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) +{ + emit_RI7(p, 0x12b, rT, rA, (d << 5) | (e << 4)); +} + + +/* Hint-for-branch instructions + */ +#if 0 +hbr; +hbra; +hbrr; +#endif + + +/* Control instructions + */ +#if 0 +stop; +EMIT_RR (spe_stopd, 0x140); +EMIT_ (spe_lnop, 0x001); +EMIT_ (spe_nop, 0x201); +sync; +EMIT_ (spe_dsync, 0x003); +EMIT_R (spe_mfspr, 0x00c); +EMIT_R (spe_mtspr, 0x10c); +#endif + +#endif /* GALLIUM_CELL */ diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h new file mode 100644 index 0000000000..10ce44b3a0 --- /dev/null +++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h @@ -0,0 +1,314 @@ +/* + * (C) Copyright IBM Corporation 2008 + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file + * Real-time assembly generation interface for Cell B.E. SPEs. + * + * \author Ian Romanick + */ + +#ifndef RTASM_PPC_SPE_H +#define RTASM_PPC_SPE_H + +struct spe_function { + /** + * + */ + uint32_t *store; + uint32_t *csr; + const char *fn; +}; + +extern void spe_init_func(struct spe_function *p, unsigned code_size); +extern void spe_release_func(struct spe_function *p); + +#endif /* RTASM_PPC_SPE_H */ + +#ifndef EMIT_ +#define EMIT_(name, _op) \ + extern void _name (struct spe_function *p, unsigned rT) +#define EMIT_R(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA) +#define EMIT_RR(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + unsigned rB) +#define EMIT_RRR(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + unsigned rB, unsigned rC) +#define EMIT_RI7(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + int imm) +#define EMIT_RI8(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + int imm) +#define EMIT_RI10(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ + int imm) +#define EMIT_RI16(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, int imm) +#define EMIT_RI18(_name, _op) \ + extern void _name (struct spe_function *p, unsigned rT, int imm) +#define EMIT_I16(_name, _op) \ + extern void _name (struct spe_function *p, int imm) +#define UNDEF_EMIT_MACROS +#endif /* EMIT_ */ + + +/* Memory load / store instructions + */ +EMIT_RI10(spe_lqd, 0x034); +EMIT_RR (spe_lqx, 0x1c4); +EMIT_RI16(spe_lqa, 0x061); +EMIT_RI16(spe_lqr, 0x067); +EMIT_RI10(spe_stqd, 0x024); +EMIT_RR (spe_stqx, 0x144); +EMIT_RI16(spe_stqa, 0x041); +EMIT_RI16(spe_stqr, 0x047); +EMIT_RI7 (spe_cbd, 0x1f4); +EMIT_RR (spe_cbx, 0x1d4); +EMIT_RI7 (spe_chd, 0x1f5); +EMIT_RI7 (spe_chx, 0x1d5); +EMIT_RI7 (spe_cwd, 0x1f6); +EMIT_RI7 (spe_cwx, 0x1d6); +EMIT_RI7 (spe_cdd, 0x1f7); +EMIT_RI7 (spe_cdx, 0x1d7); + + +/* Constant formation instructions + */ +EMIT_RI16(spe_ilh, 0x083); +EMIT_RI16(spe_ilhu, 0x082); +EMIT_RI16(spe_il, 0x081); +EMIT_RI18(spe_ila, 0x021); +EMIT_RI16(spe_iohl, 0x0c1); +EMIT_RI16(spe_fsmbi, 0x0c5); + + +/* Integer and logical instructions + */ +EMIT_RR (spe_ah, 0x0c8); +EMIT_RI10(spe_ahi, 0x01d); +EMIT_RR (spe_a, 0x0c0); +EMIT_RI10(spe_ai, 0x01c); +EMIT_RR (spe_sfh, 0x048); +EMIT_RI10(spe_sfhi, 0x00d); +EMIT_RR (spe_sf, 0x040); +EMIT_RI10(spe_sfi, 0x00c); +EMIT_RR (spe_addx, 0x340); +EMIT_RR (spe_cg, 0x0c2); +EMIT_RR (spe_cgx, 0x342); +EMIT_RR (spe_sfx, 0x341); +EMIT_RR (spe_bg, 0x042); +EMIT_RR (spe_bgx, 0x343); +EMIT_RR (spe_mpy, 0x3c4); +EMIT_RR (spe_mpyu, 0x3cc); +EMIT_RI10(spe_mpyi, 0x074); +EMIT_RI10(spe_mpyui, 0x075); +EMIT_RRR (spe_mpya, 0x00c); +EMIT_RR (spe_mpyh, 0x3c5); +EMIT_RR (spe_mpys, 0x3c7); +EMIT_RR (spe_mpyhh, 0x3c6); +EMIT_RR (spe_mpyhha, 0x346); +EMIT_RR (spe_mpyhhu, 0x3ce); +EMIT_RR (spe_mpyhhau, 0x34e); +EMIT_R (spe_clz, 0x2a5); +EMIT_R (spe_cntb, 0x2b4); +EMIT_R (spe_fsmb, 0x1b6); +EMIT_R (spe_fsmh, 0x1b5); +EMIT_R (spe_fsm, 0x1b4); +EMIT_R (spe_gbb, 0x1b2); +EMIT_R (spe_gbh, 0x1b1); +EMIT_R (spe_gb, 0x1b0); +EMIT_RR (spe_avgb, 0x0d3); +EMIT_RR (spe_absdb, 0x053); +EMIT_RR (spe_sumb, 0x253); +EMIT_R (spe_xsbh, 0x2b6); +EMIT_R (spe_xshw, 0x2ae); +EMIT_R (spe_xswd, 0x2a6); +EMIT_RR (spe_and, 0x0c1); +EMIT_RR (spe_andc, 0x2c1); +EMIT_RI10(spe_andbi, 0x016); +EMIT_RI10(spe_andhi, 0x015); +EMIT_RI10(spe_andi, 0x014); +EMIT_RR (spe_or, 0x041); +EMIT_RR (spe_orc, 0x2c9); +EMIT_RI10(spe_orbi, 0x006); +EMIT_RI10(spe_orhi, 0x005); +EMIT_RI10(spe_ori, 0x004); +EMIT_R (spe_orx, 0x1f0); +EMIT_RR (spe_xor, 0x241); +EMIT_RI10(spe_xorbi, 0x026); +EMIT_RI10(spe_xorhi, 0x025); +EMIT_RI10(spe_xori, 0x024); +EMIT_RR (spe_nand, 0x0c9); +EMIT_RR (spe_nor, 0x049); +EMIT_RR (spe_eqv, 0x249); +EMIT_RRR (spe_selb, 0x008); +EMIT_RRR (spe_shufb, 0x00b); + + +/* Shift and rotate instructions + */ +EMIT_RR (spe_shlh, 0x05f); +EMIT_RI7 (spe_shlhi, 0x07f); +EMIT_RR (spe_shl, 0x05b); +EMIT_RI7 (spe_shli, 0x07b); +EMIT_RR (spe_shlqbi, 0x1db); +EMIT_RI7 (spe_shlqbii, 0x1fb); +EMIT_RR (spe_shlqby, 0x1df); +EMIT_RI7 (spe_shlqbyi, 0x1ff); +EMIT_RR (spe_shlqbybi, 0x1cf); +EMIT_RR (spe_roth, 0x05c); +EMIT_RI7 (spe_rothi, 0x07c); +EMIT_RR (spe_rot, 0x058); +EMIT_RI7 (spe_roti, 0x078); +EMIT_RR (spe_rotqby, 0x1dc); +EMIT_RI7 (spe_rotqbyi, 0x1fc); +EMIT_RR (spe_rotqbybi, 0x1cc); +EMIT_RR (spe_rotqbi, 0x1d8); +EMIT_RI7 (spe_rotqbii, 0x1f8); +EMIT_RR (spe_rothm, 0x05d); +EMIT_RI7 (spe_rothmi, 0x07d); +EMIT_RR (spe_rotm, 0x059); +EMIT_RI7 (spe_rotmi, 0x079); +EMIT_RR (spe_rotqmby, 0x1dd); +EMIT_RI7 (spe_rotqmbyi, 0x1fd); +EMIT_RR (spe_rotqmbybi, 0x1cd); +EMIT_RR (spe_rotqmbi, 0x1c9); +EMIT_RI7 (spe_rotqmbii, 0x1f9); +EMIT_RR (spe_rotmah, 0x05e); +EMIT_RI7 (spe_rotmahi, 0x07e); +EMIT_RR (spe_rotma, 0x05a); +EMIT_RI7 (spe_rotmai, 0x07a); + + +/* Compare, branch, and halt instructions + */ +EMIT_RR (spe_heq, 0x3d8); +EMIT_RI10(spe_heqi, 0x07f); +EMIT_RR (spe_hgt, 0x258); +EMIT_RI10(spe_hgti, 0x04f); +EMIT_RR (spe_hlgt, 0x2d8); +EMIT_RI10(spe_hlgti, 0x05f); +EMIT_RR (spe_ceqb, 0x3d0); +EMIT_RI10(spe_ceqbi, 0x07e); +EMIT_RR (spe_ceqh, 0x3c8); +EMIT_RI10(spe_ceqhi, 0x07d); +EMIT_RR (spe_ceq, 0x3c0); +EMIT_RI10(spe_ceqi, 0x07c); +EMIT_RR (spe_cgtb, 0x250); +EMIT_RI10(spe_cgtbi, 0x04e); +EMIT_RR (spe_cgth, 0x248); +EMIT_RI10(spe_cgthi, 0x04d); +EMIT_RR (spe_cgt, 0x240); +EMIT_RI10(spe_cgti, 0x04c); +EMIT_RR (spe_clgtb, 0x2d0); +EMIT_RI10(spe_clgtbi, 0x05e); +EMIT_RR (spe_clgth, 0x2c8); +EMIT_RI10(spe_clgthi, 0x05d); +EMIT_RR (spe_clgt, 0x2c0); +EMIT_RI10(spe_clgti, 0x05c); +EMIT_I16 (spe_br, 0x064); +EMIT_I16 (spe_bra, 0x060); +EMIT_RI16(spe_brsl, 0x066); +EMIT_RI16(spe_brasl, 0x062); +EMIT_RI16(spe_brnz, 0x042); +EMIT_RI16(spe_brz, 0x040); +EMIT_RI16(spe_brhnz, 0x046); +EMIT_RI16(spe_brhz, 0x044); + +extern void spe_bi(struct spe_function *p, unsigned rA, int d, int e); +extern void spe_iret(struct spe_function *p, unsigned rA, int d, int e); +extern void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); +extern void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, + int d, int e); + + +/* Floating-point instructions + */ +EMIT_RR (spe_fa, 0x2c4); +EMIT_RR (spe_dfa, 0x2cc); +EMIT_RR (spe_fs, 0x2c5); +EMIT_RR (spe_dfs, 0x2cd); +EMIT_RR (spe_fm, 0x2c6); +EMIT_RR (spe_dfm, 0x2ce); +EMIT_RRR (spe_fma, 0x00e); +EMIT_RR (spe_dfma, 0x35c); +EMIT_RRR (spe_fnms, 0x00d); +EMIT_RR (spe_dfnms, 0x35e); +EMIT_RRR (spe_fms, 0x00f); +EMIT_RR (spe_dfms, 0x35d); +EMIT_RR (spe_dfnma, 0x35f); +EMIT_R (spe_frest, 0x1b8); +EMIT_R (spe_frsqest, 0x1b9); +EMIT_RR (spe_fi, 0x3d4); +EMIT_RI8 (spe_csflt, 0x1da); +EMIT_RI8 (spe_cflts, 0x1d8); +EMIT_RI8 (spe_cuflt, 0x1db); +EMIT_RI8 (spe_cfltu, 0x1d9); +EMIT_R (spe_frds, 0x3b9); +EMIT_R (spe_fesd, 0x3b8); +EMIT_RR (spe_dfceq, 0x3c3); +EMIT_RR (spe_dfcmeq, 0x3cb); +EMIT_RR (spe_dfcgt, 0x2c3); +EMIT_RR (spe_dfcmgt, 0x2cb); +EMIT_RI7 (spe_dftsv, 0x3bf); +EMIT_RR (spe_fceq, 0x3c2); +EMIT_RR (spe_fcmeq, 0x3ca); +EMIT_RR (spe_fcgt, 0x2c2); +EMIT_RR (spe_fcmgt, 0x2ca); +EMIT_R (spe_fscrwr, 0x3ba); +EMIT_ (spe_fscrrd, 0x398); + + +/* Channel instructions + */ +EMIT_R (spe_rdch, 0x00d); +EMIT_R (spe_rdchcnt, 0x00f); +EMIT_R (spe_wrch, 0x10d); + + +#ifdef UNDEF_EMIT_MACROS +#undef EMIT_ +#undef EMIT_R +#undef EMIT_RR +#undef EMIT_RRR +#undef EMIT_RI7 +#undef EMIT_RI8 +#undef EMIT_RI10 +#undef EMIT_RI16 +#undef EMIT_RI18 +#undef EMIT_I16 +#undef UNDEF_EMIT_MACROS +#endif /* EMIT_ */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 91f8e542a2..3b687bb868 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -36,7 +36,7 @@ #include "draw/draw_vbuf.h" #include "cell_winsys.h" #include "cell/common.h" -#include "ppc/rtasm/spe_asm.h" +#include "rtasm/rtasm_ppc_spe.h" struct cell_vbuf_render; diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c index f10689a959..9cf74bab47 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_fetch.c @@ -31,7 +31,7 @@ #include "../auxiliary/draw/draw_private.h" #include "cell_context.h" -#include "ppc/rtasm/spe_asm.h" +#include "rtasm/rtasm_ppc_spe.h" typedef uint64_t register_mask; diff --git a/src/mesa/ppc/rtasm/spe_asm.c b/src/mesa/ppc/rtasm/spe_asm.c deleted file mode 100644 index 1037637250..0000000000 --- a/src/mesa/ppc/rtasm/spe_asm.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2008 - * 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 - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file spe_asm.c - * Real-time assembly generation interface for Cell B.E. SPEs. - * - * \author Ian Romanick - */ -#ifdef GALLIUM_CELL -#include -#include -#include "spe_asm.h" - -/** - * SPE instruction types - * - * There are 6 primary instruction encodings used on the Cell's SPEs. Each of - * the following unions encodes one type. - * - * \bug - * If, at some point, we start generating SPE code from a little-endian host - * these unions will not work. - */ -/*@{*/ -/** - * Encode one output register with two input registers - */ -union spe_inst_RR { - uint32_t bits; - struct { - unsigned op:11; - unsigned rB:7; - unsigned rA:7; - unsigned rT:7; - } inst; -}; - - -/** - * Encode one output register with three input registers - */ -union spe_inst_RRR { - uint32_t bits; - struct { - unsigned op:4; - unsigned rT:7; - unsigned rB:7; - unsigned rA:7; - unsigned rC:7; - } inst; -}; - - -/** - * Encode one output register with one input reg. and a 7-bit signed immed - */ -union spe_inst_RI7 { - uint32_t bits; - struct { - unsigned op:11; - unsigned i7:7; - unsigned rA:7; - unsigned rT:7; - } inst; -}; - - -/** - * Encode one output register with one input reg. and an 8-bit signed immed - */ -union spe_inst_RI8 { - uint32_t bits; - struct { - unsigned op:10; - unsigned i8:8; - unsigned rA:7; - unsigned rT:7; - } inst; -}; - - -/** - * Encode one output register with one input reg. and a 10-bit signed immed - */ -union spe_inst_RI10 { - uint32_t bits; - struct { - unsigned op:8; - unsigned i10:10; - unsigned rA:7; - unsigned rT:7; - } inst; -}; - - -/** - * Encode one output register with a 16-bit signed immediate - */ -union spe_inst_RI16 { - uint32_t bits; - struct { - unsigned op:9; - unsigned i16:16; - unsigned rT:7; - } inst; -}; - - -/** - * Encode one output register with a 18-bit signed immediate - */ -union spe_inst_RI18 { - uint32_t bits; - struct { - unsigned op:7; - unsigned i18:18; - unsigned rT:7; - } inst; -}; -/*@}*/ - - -static void emit_RR(struct spe_function *p, unsigned op, unsigned rT, - unsigned rA, unsigned rB) -{ - union spe_inst_RR inst; - inst.inst.op = op; - inst.inst.rB = rB; - inst.inst.rA = rA; - inst.inst.rT = rT; - *p->csr = inst.bits; - p->csr++; -} - - -static void emit_RRR(struct spe_function *p, unsigned op, unsigned rT, - unsigned rA, unsigned rB, unsigned rC) -{ - union spe_inst_RRR inst; - inst.inst.op = op; - inst.inst.rT = rT; - inst.inst.rB = rB; - inst.inst.rA = rA; - inst.inst.rC = rC; - *p->csr = inst.bits; - p->csr++; -} - - -static void emit_RI7(struct spe_function *p, unsigned op, unsigned rT, - unsigned rA, int imm) -{ - union spe_inst_RI7 inst; - inst.inst.op = op; - inst.inst.i7 = imm; - inst.inst.rA = rA; - inst.inst.rT = rT; - *p->csr = inst.bits; - p->csr++; -} - - - -static void emit_RI8(struct spe_function *p, unsigned op, unsigned rT, - unsigned rA, int imm) -{ - union spe_inst_RI8 inst; - inst.inst.op = op; - inst.inst.i8 = imm; - inst.inst.rA = rA; - inst.inst.rT = rT; - *p->csr = inst.bits; - p->csr++; -} - - - -static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT, - unsigned rA, int imm) -{ - union spe_inst_RI10 inst; - inst.inst.op = op; - inst.inst.i10 = imm; - inst.inst.rA = rA; - inst.inst.rT = rT; - *p->csr = inst.bits; - p->csr++; -} - - -static void emit_RI16(struct spe_function *p, unsigned op, unsigned rT, - int imm) -{ - union spe_inst_RI16 inst; - inst.inst.op = op; - inst.inst.i16 = imm; - inst.inst.rT = rT; - *p->csr = inst.bits; - p->csr++; -} - - -static void emit_RI18(struct spe_function *p, unsigned op, unsigned rT, - int imm) -{ - union spe_inst_RI18 inst; - inst.inst.op = op; - inst.inst.i18 = imm; - inst.inst.rT = rT; - *p->csr = inst.bits; - p->csr++; -} - - - - -#define EMIT_(_name, _op) \ -void _name (struct spe_function *p, unsigned rT) \ -{ \ - emit_RR(p, _op, rT, 0, 0); \ -} - -#define EMIT_R(_name, _op) \ -void _name (struct spe_function *p, unsigned rT, unsigned rA) \ -{ \ - emit_RR(p, _op, rT, rA, 0); \ -} - -#define EMIT_RR(_name, _op) \ -void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB) \ -{ \ - emit_RR(p, _op, rT, rA, rB); \ -} - -#define EMIT_RRR(_name, _op) \ -void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB, unsigned rC) \ -{ \ - emit_RRR(p, _op, rT, rA, rB, rC); \ -} - -#define EMIT_RI7(_name, _op) \ -void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ -{ \ - emit_RI7(p, _op, rT, rA, imm); \ -} - -#define EMIT_RI8(_name, _op) \ -void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ -{ \ - emit_RI8(p, _op, rT, rA, 155 - imm); \ -} - -#define EMIT_RI10(_name, _op) \ -void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \ -{ \ - emit_RI10(p, _op, rT, rA, imm); \ -} - -#define EMIT_RI16(_name, _op) \ -void _name (struct spe_function *p, unsigned rT, int imm) \ -{ \ - emit_RI16(p, _op, rT, imm); \ -} - -#define EMIT_RI18(_name, _op) \ -void _name (struct spe_function *p, unsigned rT, int imm) \ -{ \ - emit_RI18(p, _op, rT, imm); \ -} - -#define EMIT_I16(_name, _op) \ -void _name (struct spe_function *p, int imm) \ -{ \ - emit_RI16(p, _op, 0, imm); \ -} - -#include "spe_asm.h" - - -/* - */ -void spe_init_func(struct spe_function *p, unsigned code_size) -{ - p->store = _mesa_align_malloc(code_size, 16); - p->csr = p->store; -} - - -void spe_release_func(struct spe_function *p) -{ - _mesa_align_free(p->store); - p->store = NULL; - p->csr = NULL; -} - - -void spe_bi(struct spe_function *p, unsigned rA, int d, int e) -{ - emit_RI7(p, 0x1a8, 0, rA, (d << 5) | (e << 4)); -} - -void spe_iret(struct spe_function *p, unsigned rA, int d, int e) -{ - emit_RI7(p, 0x1aa, 0, rA, (d << 5) | (e << 4)); -} - -void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, int d, - int e) -{ - emit_RI7(p, 0x1ab, rT, rA, (d << 5) | (e << 4)); -} - -void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, int d, - int e) -{ - emit_RI7(p, 0x1a9, rT, rA, (d << 5) | (e << 4)); -} - -void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, int d, - int e) -{ - emit_RI7(p, 0x128, rT, rA, (d << 5) | (e << 4)); -} - -void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) -{ - emit_RI7(p, 0x129, rT, rA, (d << 5) | (e << 4)); -} - -void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) -{ - emit_RI7(p, 0x12a, rT, rA, (d << 5) | (e << 4)); -} - -void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e) -{ - emit_RI7(p, 0x12b, rT, rA, (d << 5) | (e << 4)); -} - - -/* Hint-for-branch instructions - */ -#if 0 -hbr; -hbra; -hbrr; -#endif - - -/* Control instructions - */ -#if 0 -stop; -EMIT_RR (spe_stopd, 0x140); -EMIT_ (spe_lnop, 0x001); -EMIT_ (spe_nop, 0x201); -sync; -EMIT_ (spe_dsync, 0x003); -EMIT_R (spe_mfspr, 0x00c); -EMIT_R (spe_mtspr, 0x10c); -#endif - -#endif /* GALLIUM_CELL */ diff --git a/src/mesa/ppc/rtasm/spe_asm.h b/src/mesa/ppc/rtasm/spe_asm.h deleted file mode 100644 index 6d69ae655d..0000000000 --- a/src/mesa/ppc/rtasm/spe_asm.h +++ /dev/null @@ -1,314 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2008 - * 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 - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file spe_asm.h - * Real-time assembly generation interface for Cell B.E. SPEs. - * - * \author Ian Romanick - */ - -#ifndef SPE_ASM_H -#define SPE_ASM_H - -struct spe_function { - /** - * - */ - uint32_t *store; - uint32_t *csr; - const char *fn; -}; - -extern void spe_init_func(struct spe_function *p, unsigned code_size); -extern void spe_release_func(struct spe_function *p); - -#endif /* SPE_ASM_H */ - -#ifndef EMIT_ -#define EMIT_(name, _op) \ - extern void _name (struct spe_function *p, unsigned rT) -#define EMIT_R(_name, _op) \ - extern void _name (struct spe_function *p, unsigned rT, unsigned rA) -#define EMIT_RR(_name, _op) \ - extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ - unsigned rB) -#define EMIT_RRR(_name, _op) \ - extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ - unsigned rB, unsigned rC) -#define EMIT_RI7(_name, _op) \ - extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ - int imm) -#define EMIT_RI8(_name, _op) \ - extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ - int imm) -#define EMIT_RI10(_name, _op) \ - extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \ - int imm) -#define EMIT_RI16(_name, _op) \ - extern void _name (struct spe_function *p, unsigned rT, int imm) -#define EMIT_RI18(_name, _op) \ - extern void _name (struct spe_function *p, unsigned rT, int imm) -#define EMIT_I16(_name, _op) \ - extern void _name (struct spe_function *p, int imm) -#define UNDEF_EMIT_MACROS -#endif /* EMIT_ */ - - -/* Memory load / store instructions - */ -EMIT_RI10(spe_lqd, 0x034); -EMIT_RR (spe_lqx, 0x1c4); -EMIT_RI16(spe_lqa, 0x061); -EMIT_RI16(spe_lqr, 0x067); -EMIT_RI10(spe_stqd, 0x024); -EMIT_RR (spe_stqx, 0x144); -EMIT_RI16(spe_stqa, 0x041); -EMIT_RI16(spe_stqr, 0x047); -EMIT_RI7 (spe_cbd, 0x1f4); -EMIT_RR (spe_cbx, 0x1d4); -EMIT_RI7 (spe_chd, 0x1f5); -EMIT_RI7 (spe_chx, 0x1d5); -EMIT_RI7 (spe_cwd, 0x1f6); -EMIT_RI7 (spe_cwx, 0x1d6); -EMIT_RI7 (spe_cdd, 0x1f7); -EMIT_RI7 (spe_cdx, 0x1d7); - - -/* Constant formation instructions - */ -EMIT_RI16(spe_ilh, 0x083); -EMIT_RI16(spe_ilhu, 0x082); -EMIT_RI16(spe_il, 0x081); -EMIT_RI18(spe_ila, 0x021); -EMIT_RI16(spe_iohl, 0x0c1); -EMIT_RI16(spe_fsmbi, 0x0c5); - - -/* Integer and logical instructions - */ -EMIT_RR (spe_ah, 0x0c8); -EMIT_RI10(spe_ahi, 0x01d); -EMIT_RR (spe_a, 0x0c0); -EMIT_RI10(spe_ai, 0x01c); -EMIT_RR (spe_sfh, 0x048); -EMIT_RI10(spe_sfhi, 0x00d); -EMIT_RR (spe_sf, 0x040); -EMIT_RI10(spe_sfi, 0x00c); -EMIT_RR (spe_addx, 0x340); -EMIT_RR (spe_cg, 0x0c2); -EMIT_RR (spe_cgx, 0x342); -EMIT_RR (spe_sfx, 0x341); -EMIT_RR (spe_bg, 0x042); -EMIT_RR (spe_bgx, 0x343); -EMIT_RR (spe_mpy, 0x3c4); -EMIT_RR (spe_mpyu, 0x3cc); -EMIT_RI10(spe_mpyi, 0x074); -EMIT_RI10(spe_mpyui, 0x075); -EMIT_RRR (spe_mpya, 0x00c); -EMIT_RR (spe_mpyh, 0x3c5); -EMIT_RR (spe_mpys, 0x3c7); -EMIT_RR (spe_mpyhh, 0x3c6); -EMIT_RR (spe_mpyhha, 0x346); -EMIT_RR (spe_mpyhhu, 0x3ce); -EMIT_RR (spe_mpyhhau, 0x34e); -EMIT_R (spe_clz, 0x2a5); -EMIT_R (spe_cntb, 0x2b4); -EMIT_R (spe_fsmb, 0x1b6); -EMIT_R (spe_fsmh, 0x1b5); -EMIT_R (spe_fsm, 0x1b4); -EMIT_R (spe_gbb, 0x1b2); -EMIT_R (spe_gbh, 0x1b1); -EMIT_R (spe_gb, 0x1b0); -EMIT_RR (spe_avgb, 0x0d3); -EMIT_RR (spe_absdb, 0x053); -EMIT_RR (spe_sumb, 0x253); -EMIT_R (spe_xsbh, 0x2b6); -EMIT_R (spe_xshw, 0x2ae); -EMIT_R (spe_xswd, 0x2a6); -EMIT_RR (spe_and, 0x0c1); -EMIT_RR (spe_andc, 0x2c1); -EMIT_RI10(spe_andbi, 0x016); -EMIT_RI10(spe_andhi, 0x015); -EMIT_RI10(spe_andi, 0x014); -EMIT_RR (spe_or, 0x041); -EMIT_RR (spe_orc, 0x2c9); -EMIT_RI10(spe_orbi, 0x006); -EMIT_RI10(spe_orhi, 0x005); -EMIT_RI10(spe_ori, 0x004); -EMIT_R (spe_orx, 0x1f0); -EMIT_RR (spe_xor, 0x241); -EMIT_RI10(spe_xorbi, 0x026); -EMIT_RI10(spe_xorhi, 0x025); -EMIT_RI10(spe_xori, 0x024); -EMIT_RR (spe_nand, 0x0c9); -EMIT_RR (spe_nor, 0x049); -EMIT_RR (spe_eqv, 0x249); -EMIT_RRR (spe_selb, 0x008); -EMIT_RRR (spe_shufb, 0x00b); - - -/* Shift and rotate instructions - */ -EMIT_RR (spe_shlh, 0x05f); -EMIT_RI7 (spe_shlhi, 0x07f); -EMIT_RR (spe_shl, 0x05b); -EMIT_RI7 (spe_shli, 0x07b); -EMIT_RR (spe_shlqbi, 0x1db); -EMIT_RI7 (spe_shlqbii, 0x1fb); -EMIT_RR (spe_shlqby, 0x1df); -EMIT_RI7 (spe_shlqbyi, 0x1ff); -EMIT_RR (spe_shlqbybi, 0x1cf); -EMIT_RR (spe_roth, 0x05c); -EMIT_RI7 (spe_rothi, 0x07c); -EMIT_RR (spe_rot, 0x058); -EMIT_RI7 (spe_roti, 0x078); -EMIT_RR (spe_rotqby, 0x1dc); -EMIT_RI7 (spe_rotqbyi, 0x1fc); -EMIT_RR (spe_rotqbybi, 0x1cc); -EMIT_RR (spe_rotqbi, 0x1d8); -EMIT_RI7 (spe_rotqbii, 0x1f8); -EMIT_RR (spe_rothm, 0x05d); -EMIT_RI7 (spe_rothmi, 0x07d); -EMIT_RR (spe_rotm, 0x059); -EMIT_RI7 (spe_rotmi, 0x079); -EMIT_RR (spe_rotqmby, 0x1dd); -EMIT_RI7 (spe_rotqmbyi, 0x1fd); -EMIT_RR (spe_rotqmbybi, 0x1cd); -EMIT_RR (spe_rotqmbi, 0x1c9); -EMIT_RI7 (spe_rotqmbii, 0x1f9); -EMIT_RR (spe_rotmah, 0x05e); -EMIT_RI7 (spe_rotmahi, 0x07e); -EMIT_RR (spe_rotma, 0x05a); -EMIT_RI7 (spe_rotmai, 0x07a); - - -/* Compare, branch, and halt instructions - */ -EMIT_RR (spe_heq, 0x3d8); -EMIT_RI10(spe_heqi, 0x07f); -EMIT_RR (spe_hgt, 0x258); -EMIT_RI10(spe_hgti, 0x04f); -EMIT_RR (spe_hlgt, 0x2d8); -EMIT_RI10(spe_hlgti, 0x05f); -EMIT_RR (spe_ceqb, 0x3d0); -EMIT_RI10(spe_ceqbi, 0x07e); -EMIT_RR (spe_ceqh, 0x3c8); -EMIT_RI10(spe_ceqhi, 0x07d); -EMIT_RR (spe_ceq, 0x3c0); -EMIT_RI10(spe_ceqi, 0x07c); -EMIT_RR (spe_cgtb, 0x250); -EMIT_RI10(spe_cgtbi, 0x04e); -EMIT_RR (spe_cgth, 0x248); -EMIT_RI10(spe_cgthi, 0x04d); -EMIT_RR (spe_cgt, 0x240); -EMIT_RI10(spe_cgti, 0x04c); -EMIT_RR (spe_clgtb, 0x2d0); -EMIT_RI10(spe_clgtbi, 0x05e); -EMIT_RR (spe_clgth, 0x2c8); -EMIT_RI10(spe_clgthi, 0x05d); -EMIT_RR (spe_clgt, 0x2c0); -EMIT_RI10(spe_clgti, 0x05c); -EMIT_I16 (spe_br, 0x064); -EMIT_I16 (spe_bra, 0x060); -EMIT_RI16(spe_brsl, 0x066); -EMIT_RI16(spe_brasl, 0x062); -EMIT_RI16(spe_brnz, 0x042); -EMIT_RI16(spe_brz, 0x040); -EMIT_RI16(spe_brhnz, 0x046); -EMIT_RI16(spe_brhz, 0x044); - -extern void spe_bi(struct spe_function *p, unsigned rA, int d, int e); -extern void spe_iret(struct spe_function *p, unsigned rA, int d, int e); -extern void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, - int d, int e); -extern void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, - int d, int e); -extern void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, - int d, int e); -extern void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, - int d, int e); -extern void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, - int d, int e); -extern void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, - int d, int e); - - -/* Floating-point instructions - */ -EMIT_RR (spe_fa, 0x2c4); -EMIT_RR (spe_dfa, 0x2cc); -EMIT_RR (spe_fs, 0x2c5); -EMIT_RR (spe_dfs, 0x2cd); -EMIT_RR (spe_fm, 0x2c6); -EMIT_RR (spe_dfm, 0x2ce); -EMIT_RRR (spe_fma, 0x00e); -EMIT_RR (spe_dfma, 0x35c); -EMIT_RRR (spe_fnms, 0x00d); -EMIT_RR (spe_dfnms, 0x35e); -EMIT_RRR (spe_fms, 0x00f); -EMIT_RR (spe_dfms, 0x35d); -EMIT_RR (spe_dfnma, 0x35f); -EMIT_R (spe_frest, 0x1b8); -EMIT_R (spe_frsqest, 0x1b9); -EMIT_RR (spe_fi, 0x3d4); -EMIT_RI8 (spe_csflt, 0x1da); -EMIT_RI8 (spe_cflts, 0x1d8); -EMIT_RI8 (spe_cuflt, 0x1db); -EMIT_RI8 (spe_cfltu, 0x1d9); -EMIT_R (spe_frds, 0x3b9); -EMIT_R (spe_fesd, 0x3b8); -EMIT_RR (spe_dfceq, 0x3c3); -EMIT_RR (spe_dfcmeq, 0x3cb); -EMIT_RR (spe_dfcgt, 0x2c3); -EMIT_RR (spe_dfcmgt, 0x2cb); -EMIT_RI7 (spe_dftsv, 0x3bf); -EMIT_RR (spe_fceq, 0x3c2); -EMIT_RR (spe_fcmeq, 0x3ca); -EMIT_RR (spe_fcgt, 0x2c2); -EMIT_RR (spe_fcmgt, 0x2ca); -EMIT_R (spe_fscrwr, 0x3ba); -EMIT_ (spe_fscrrd, 0x398); - - -/* Channel instructions - */ -EMIT_R (spe_rdch, 0x00d); -EMIT_R (spe_rdchcnt, 0x00f); -EMIT_R (spe_wrch, 0x10d); - - -#ifdef UNDEF_EMIT_MACROS -#undef EMIT_ -#undef EMIT_R -#undef EMIT_RR -#undef EMIT_RRR -#undef EMIT_RI7 -#undef EMIT_RI8 -#undef EMIT_RI10 -#undef EMIT_RI16 -#undef EMIT_RI18 -#undef EMIT_I16 -#undef UNDEF_EMIT_MACROS -#endif /* EMIT_ */ diff --git a/src/mesa/sources b/src/mesa/sources index 9e56694893..f0bf7b31fb 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -246,7 +246,6 @@ ASM_C_SOURCES = \ x86/rtasm/x86sse.c \ sparc/sparc.c \ ppc/common_ppc.c \ - ppc/rtasm/spe_asm.c \ x86-64/x86-64.c X86_SOURCES = \ -- cgit v1.2.3 From b9da3791c934e05b82063a8c79c423a0a8e29a94 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 15:07:53 +0900 Subject: Remove src/mesa and src/mesa/main from gallium source include paths. --- SConstruct | 2 - src/gallium/Makefile.template | 2 - src/gallium/auxiliary/draw/draw_vf_sse.c | 3 +- src/gallium/auxiliary/pipebuffer/linked_list.h | 91 ------ .../auxiliary/pipebuffer/pb_buffer_fenced.c | 3 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 3 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 3 +- src/gallium/auxiliary/util/u_double_list.h | 91 ++++++ src/gallium/auxiliary/util/u_simple_list.h | 197 +++++++++++++ src/gallium/drivers/i915simple/i915_debug.c | 2 - src/gallium/include/pipe/p_thread.h | 327 +++++++++++++++++++-- src/gallium/winsys/dri/intel/SConscript | 2 +- src/gallium/winsys/dri/intel/intel_batchpool.c | 15 +- src/gallium/winsys/xlib/SConscript | 6 + src/gallium/winsys/xlib/brw_aub.c | 16 +- src/mesa/SConscript | 7 + src/mesa/x86/common_x86_asm.S | 2 +- 17 files changed, 620 insertions(+), 152 deletions(-) delete mode 100644 src/gallium/auxiliary/pipebuffer/linked_list.h create mode 100644 src/gallium/auxiliary/util/u_double_list.h create mode 100644 src/gallium/auxiliary/util/u_simple_list.h (limited to 'src') diff --git a/SConstruct b/SConstruct index b20f88a303..6cb07302e8 100644 --- a/SConstruct +++ b/SConstruct @@ -109,8 +109,6 @@ else: # Includes env.Append(CPPPATH = [ '#/include', - '#/src/mesa', - '#/src/mesa/main', '#/src/gallium/include', '#/src/gallium/auxiliary', '#/src/gallium/drivers', diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 6698212e77..4e462b5c97 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -18,8 +18,6 @@ INCLUDES = \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ -I$(TOP)/include \ $(DRIVER_INCLUDES) diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c index 6076f9849d..aff4ffd985 100644 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ b/src/gallium/auxiliary/draw/draw_vf_sse.c @@ -26,9 +26,8 @@ */ -#include "simple_list.h" - #include "pipe/p_compiler.h" +#include "util/u_simple_list.h" #include "draw_vf.h" diff --git a/src/gallium/auxiliary/pipebuffer/linked_list.h b/src/gallium/auxiliary/pipebuffer/linked_list.h deleted file mode 100644 index e99817fb13..0000000000 --- a/src/gallium/auxiliary/pipebuffer/linked_list.h +++ /dev/null @@ -1,91 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - **************************************************************************/ - -/** - * \file - * List macros heavily inspired by the Linux kernel - * list handling. No list looping yet. - * - * Is not threadsafe, so common operations need to - * be protected using an external mutex. - */ - -#ifndef LINKED_LIST_H_ -#define LINKED_LIST_H_ - - -#include - - -struct list_head -{ - struct list_head *prev; - struct list_head *next; -}; - - -#define LIST_INITHEAD(__item) \ - do { \ - (__item)->prev = (__item); \ - (__item)->next = (__item); \ - } while (0) - -#define LIST_ADD(__item, __list) \ - do { \ - (__item)->prev = (__list); \ - (__item)->next = (__list)->next; \ - (__list)->next->prev = (__item); \ - (__list)->next = (__item); \ - } while (0) - -#define LIST_ADDTAIL(__item, __list) \ - do { \ - (__item)->next = (__list); \ - (__item)->prev = (__list)->prev; \ - (__list)->prev->next = (__item); \ - (__list)->prev = (__item); \ - } while(0) - -#define LIST_DEL(__item) \ - do { \ - (__item)->prev->next = (__item)->next; \ - (__item)->next->prev = (__item)->prev; \ - } while(0) - -#define LIST_DELINIT(__item) \ - do { \ - (__item)->prev->next = (__item)->next; \ - (__item)->next->prev = (__item)->prev; \ - (__item)->next = (__item); \ - (__item)->prev = (__item); \ - } while(0) - -#define LIST_ENTRY(__type, __item, __field) \ - ((__type *)(((char *)(__item)) - offsetof(__type, __field))) - - -#endif /*LINKED_LIST_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index bc85c4b19f..e2ee72ed1f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -34,13 +34,12 @@ */ -#include "linked_list.h" - #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_winsys.h" #include "pipe/p_thread.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 983a105347..ff4fd123f3 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -33,12 +33,11 @@ */ -#include "linked_list.h" - #include "pipe/p_defines.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "util/u_mm.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index beb145b7cb..528e9528f6 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -35,13 +35,12 @@ */ -#include "linked_list.h" - #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/util/u_double_list.h b/src/gallium/auxiliary/util/u_double_list.h new file mode 100644 index 0000000000..8cb10c9820 --- /dev/null +++ b/src/gallium/auxiliary/util/u_double_list.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. + * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +/** + * \file + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + * + * Is not threadsafe, so common operations need to + * be protected using an external mutex. + */ + +#ifndef _U_DOUBLE_LIST_H_ +#define _U_DOUBLE_LIST_H_ + + +#include + + +struct list_head +{ + struct list_head *prev; + struct list_head *next; +}; + + +#define LIST_INITHEAD(__item) \ + do { \ + (__item)->prev = (__item); \ + (__item)->next = (__item); \ + } while (0) + +#define LIST_ADD(__item, __list) \ + do { \ + (__item)->prev = (__list); \ + (__item)->next = (__list)->next; \ + (__list)->next->prev = (__item); \ + (__list)->next = (__item); \ + } while (0) + +#define LIST_ADDTAIL(__item, __list) \ + do { \ + (__item)->next = (__list); \ + (__item)->prev = (__list)->prev; \ + (__list)->prev->next = (__item); \ + (__list)->prev = (__item); \ + } while(0) + +#define LIST_DEL(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + } while(0) + +#define LIST_DELINIT(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + (__item)->next = (__item); \ + (__item)->prev = (__item); \ + } while(0) + +#define LIST_ENTRY(__type, __item, __field) \ + ((__type *)(((char *)(__item)) - offsetof(__type, __field))) + + +#endif /*_U_DOUBLE_LIST_H_*/ diff --git a/src/gallium/auxiliary/util/u_simple_list.h b/src/gallium/auxiliary/util/u_simple_list.h new file mode 100644 index 0000000000..f5f43b0faa --- /dev/null +++ b/src/gallium/auxiliary/util/u_simple_list.h @@ -0,0 +1,197 @@ +/** + * \file simple_list.h + * Simple macros for type-safe, intrusive lists. + * + * Intended to work with a list sentinal which is created as an empty + * list. Insert & delete are O(1). + * + * \author + * (C) 1997, Keith Whitwell + */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _U_SIMPLE_LIST_H_ +#define _U_SIMPLE_LIST_H_ + +/** + * Remove an element from list. + * + * \param elem element to remove. + */ +#define remove_from_list(elem) \ +do { \ + (elem)->next->prev = (elem)->prev; \ + (elem)->prev->next = (elem)->next; \ +} while (0) + +/** + * Insert an element to the list head. + * + * \param list list. + * \param elem element to insert. + */ +#define insert_at_head(list, elem) \ +do { \ + (elem)->prev = list; \ + (elem)->next = (list)->next; \ + (list)->next->prev = elem; \ + (list)->next = elem; \ +} while(0) + +/** + * Insert an element to the list tail. + * + * \param list list. + * \param elem element to insert. + */ +#define insert_at_tail(list, elem) \ +do { \ + (elem)->next = list; \ + (elem)->prev = (list)->prev; \ + (list)->prev->next = elem; \ + (list)->prev = elem; \ +} while(0) + +/** + * Move an element to the list head. + * + * \param list list. + * \param elem element to move. + */ +#define move_to_head(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_head(list, elem); \ +} while (0) + +/** + * Move an element to the list tail. + * + * \param list list. + * \param elem element to move. + */ +#define move_to_tail(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_tail(list, elem); \ +} while (0) + +/** + * Make a empty list empty. + * + * \param sentinal list (sentinal element). + */ +#define make_empty_list(sentinal) \ +do { \ + (sentinal)->next = sentinal; \ + (sentinal)->prev = sentinal; \ +} while (0) + +/** + * Get list first element. + * + * \param list list. + * + * \return pointer to first element. + */ +#define first_elem(list) ((list)->next) + +/** + * Get list last element. + * + * \param list list. + * + * \return pointer to last element. + */ +#define last_elem(list) ((list)->prev) + +/** + * Get next element. + * + * \param elem element. + * + * \return pointer to next element. + */ +#define next_elem(elem) ((elem)->next) + +/** + * Get previous element. + * + * \param elem element. + * + * \return pointer to previous element. + */ +#define prev_elem(elem) ((elem)->prev) + +/** + * Test whether element is at end of the list. + * + * \param list list. + * \param elem element. + * + * \return non-zero if element is at end of list, or zero otherwise. + */ +#define at_end(list, elem) ((elem) == (list)) + +/** + * Test if a list is empty. + * + * \param list list. + * + * \return non-zero if list empty, or zero otherwise. + */ +#define is_empty_list(list) ((list)->next == (list)) + +/** + * Walk through the elements of a list. + * + * \param ptr pointer to the current element. + * \param list list. + * + * \note It should be followed by a { } block or a single statement, as in a \c + * for loop. + */ +#define foreach(ptr, list) \ + for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) + +/** + * Walk through the elements of a list. + * + * Same as #foreach but lets you unlink the current value during a list + * traversal. Useful for freeing a list, element by element. + * + * \param ptr pointer to the current element. + * \param t temporary pointer. + * \param list list. + * + * \note It should be followed by a { } block or a single statement, as in a \c + * for loop. + */ +#define foreach_s(ptr, t, list) \ + for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) + +#endif /* _U_SIMPLE_LIST_H_ */ diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c index 94db44e1aa..78102dbac2 100644 --- a/src/gallium/drivers/i915simple/i915_debug.c +++ b/src/gallium/drivers/i915simple/i915_debug.c @@ -25,8 +25,6 @@ * **************************************************************************/ -//#include "imports.h" - #include "i915_reg.h" #include "i915_context.h" #include "i915_winsys.h" diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h index cd432c547c..4325abc951 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/include/pipe/p_thread.h @@ -1,54 +1,317 @@ /************************************************************************** * + * Copyright 1999-2006 Brian Paul * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. * 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, sub license, 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. - * + * 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ -#ifndef P_THREAD_H -#define P_THREAD_H +/** + * @file + * Thread + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * + * + * + * DOCUMENTATION + * + * This thread module exports the following types: + * _glthread_TSD Thread-specific data area + * _glthread_Thread Thread datatype + * _glthread_Mutex Mutual exclusion lock + * + * Macros: + * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex + * _glthread_INIT_MUTEX(name) Initialize a mutex + * _glthread_LOCK_MUTEX(name) Lock a mutex + * _glthread_UNLOCK_MUTEX(name) Unlock a mutex + * + * Functions: + * _glthread_GetID(v) Get integer thread ID + * _glthread_InitTSD() Initialize thread-specific data + * _glthread_GetTSD() Get thread-specific data + * _glthread_SetTSD() Set thread-specific data + * + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef _P_THREAD_H_ +#define _P_THREAD_H_ + + +#if defined(USE_MGL_NAMESPACE) +#define _glapi_Dispatch _mglapi_Dispatch +#endif + + + +#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ + defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ + && !defined(THREADS) +# define THREADS +#endif + +#ifdef VMS +#include +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(PTHREADS) +#include /* POSIX threads headers */ + +typedef struct { + pthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef pthread_t _glthread_Thread; + +typedef pthread_mutex_t _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + pthread_mutex_init(&(name), NULL) + +#define _glthread_DESTROY_MUTEX(name) \ + pthread_mutex_destroy(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) pthread_mutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) pthread_mutex_unlock(&(name)) + +#endif /* PTHREADS */ + + + + +/* + * Solaris threads. Use only up to Solaris 2.4. + * Solaris 2.5 and higher provide POSIX threads. + * Be sure to compile with -mt on the Solaris compilers, or + * use -D_REENTRANT if using gcc. + */ +#ifdef SOLARIS_THREADS +#include + +typedef struct { + thread_key_t key; + mutex_t keylock; + int initMagic; +} _glthread_TSD; + +typedef thread_t _glthread_Thread; + +typedef mutex_t _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 +#define _glthread_INIT_MUTEX(name) (void) name +#define _glthread_DESTROY_MUTEX(name) (void) name +#define _glthread_LOCK_MUTEX(name) (void) name +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* SOLARIS_THREADS */ + + + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include + +typedef struct { + DWORD key; + int initMagic; +} _glthread_TSD; + +typedef HANDLE _glthread_Thread; + +typedef CRITICAL_SECTION _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} +#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) +#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) +#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) +#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) + +#endif /* WIN32_THREADS */ + + -#include "p_compiler.h" /* - * XXX: We should come up with a system-independent thread definitions. - * XXX: Patching glthread defs for now. + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. */ +#ifdef USE_XTHREADS +#include + +typedef struct { + xthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef xthread_t _glthread_Thread; + +typedef xmutex_rec _glthread_Mutex; + +#ifdef XMUTEX_INITIALIZER +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = XMUTEX_INITIALIZER +#else +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name +#endif + +#define _glthread_INIT_MUTEX(name) \ + xmutex_init(&(name)) + +#define _glthread_DESTROY_MUTEX(name) \ + xmutex_clear(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) xmutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) xmutex_unlock(&(name)) + +#endif /* USE_XTHREADS */ + + + +/* + * BeOS threads. R5.x required. + */ +#ifdef BEOS_THREADS + +#include +#include + +typedef struct { + int32 key; + int initMagic; +} _glthread_TSD; + +typedef thread_id _glthread_Thread; + +/* Use Benaphore, aka speeder semaphore */ +typedef struct { + int32 lock; + sem_id sem; +} benaphore; +typedef benaphore _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } +#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 +#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 +#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ + if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) +#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) + +#endif /* BEOS_THREADS */ + + + +#ifndef THREADS + +/* + * THREADS not defined + */ + +typedef unsigned _glthread_TSD; + +typedef unsigned _glthread_Thread; + +typedef unsigned _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 + +#define _glthread_INIT_MUTEX(name) (void) name + +#define _glthread_DESTROY_MUTEX(name) (void) name + +#define _glthread_LOCK_MUTEX(name) (void) name + +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* THREADS */ + + + +/* + * Platform independent thread specific data API. + */ + +extern unsigned long +_glthread_GetID(void); + + +extern void +_glthread_InitTSD(_glthread_TSD *); + + +extern void * +_glthread_GetTSD(_glthread_TSD *); -#ifndef __MSC__ -#include "glapi/glthread.h" +extern void +_glthread_SetTSD(_glthread_TSD *, void *); -#else /* __MSC__ */ +#if defined(GLX_USE_TLS) -typedef int _glthread_Mutex; +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); -#define _glthread_INIT_MUTEX( M ) ((void) (M)) -#define _glthread_LOCK_MUTEX( M ) ((void) (M)) -#define _glthread_UNLOCK_MUTEX( M ) ((void) (M)) +#define GET_DISPATCH() _glapi_tls_Dispatch -#define sched_yield() ((void) 0) +#elif !defined(GL_CALL) +# if defined(THREADS) +# define GET_DISPATCH() \ + ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ + ? _glapi_Dispatch : _glapi_get_dispatch()) +# else +# define GET_DISPATCH() _glapi_Dispatch +# endif /* defined(THREADS) */ +#endif /* ndef GL_CALL */ -#endif /* __MSC__ */ -#endif /* P_THREAD_H */ +#endif /* _P_THREAD_H_ */ diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index 525ba580e8..0ad19d42a8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -35,5 +35,5 @@ drivers = [ env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = mesa + drivers + auxiliaries + env['LIBS'], + LIBS = drivers + mesa + auxiliaries + env['LIBS'], ) \ No newline at end of file diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c index 33b56817f6..ce154c7b88 100644 --- a/src/gallium/winsys/dri/intel/intel_batchpool.c +++ b/src/gallium/winsys/dri/intel/intel_batchpool.c @@ -36,9 +36,12 @@ #include #include +#include #include -#include "imports.h" -#include "glthread.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_thread.h" + #include "dri_bufpool.h" #include "dri_bufmgr.h" #include "intel_batchpool.h" @@ -196,7 +199,7 @@ pool_create(struct _DriBufferPool *pool, _glthread_LOCK_MUTEX(p->mutex); if (p->numFree == 0) - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); if (p->numFree == 0) { fprintf(stderr, "Out of fixed size buffer objects\n"); @@ -278,7 +281,7 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, return -EBUSY; } - buf->mapped = GL_TRUE; + buf->mapped = TRUE; *virtual = (unsigned char *) p->virtual + buf->start; _glthread_UNLOCK_MUTEX(p->mutex); return 0; @@ -361,7 +364,7 @@ pool_validate(struct _DriBufferPool *pool, void *private) BBuf *buf = (BBuf *) private; BPool *p = buf->parent; _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = GL_TRUE; + buf->unfenced = TRUE; _glthread_UNLOCK_MUTEX(p->mutex); return 0; } @@ -379,7 +382,7 @@ pool_takedown(struct _DriBufferPool *pool) while ((p->numFree < p->numTot) && p->numDelayed) { _glthread_UNLOCK_MUTEX(p->mutex); sched_yield(); - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); _glthread_LOCK_MUTEX(p->mutex); } diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index f8aa5ef945..c38b5be52c 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,6 +3,12 @@ Import('*') +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', +]) sources = [ 'glxapi.c', diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 541d50c6e4..10eedd8402 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -29,11 +29,13 @@ * Keith Whitwell */ +#include +#include #include "brw_aub.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "imports.h" -//#include "intel_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" struct brw_aubfile { @@ -350,9 +352,9 @@ struct brw_aubfile *brw_aubfile_create( void ) i++; - if (_mesa_getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); - _mesa_printf("--> Aub file: %s\n", filename); + if (getenv("INTEL_AUBFILE")) { + val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } else { @@ -360,12 +362,12 @@ struct brw_aubfile *brw_aubfile_create( void ) if (val < 0 || val > sizeof(filename)) strcpy(filename, "default.aub"); - _mesa_printf("--> Aub file: %s\n", filename); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } if (!aubfile->file) { - _mesa_printf("couldn't open aubfile\n"); + debug_printf("couldn't open aubfile\n"); exit(1); } diff --git a/src/mesa/SConscript b/src/mesa/SConscript index a828133580..db18c61fac 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -4,6 +4,13 @@ Import('*') +env = env.Clone() + +# Includes +env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', +]) ####################################################################### # Core sources diff --git a/src/mesa/x86/common_x86_asm.S b/src/mesa/x86/common_x86_asm.S index ef3cc9eb59..09c86b05ba 100644 --- a/src/mesa/x86/common_x86_asm.S +++ b/src/mesa/x86/common_x86_asm.S @@ -39,7 +39,7 @@ * in there will break the build on some platforms. */ -#include "matypes.h" +#include "assyntax.h" #include "common_x86_features.h" SEG_TEXT -- cgit v1.2.3 From b62f0ddd09f8ef9c400feca321412b3f0bc77e63 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 18:56:55 +0900 Subject: Portability fixes. Eliminate C99/C++ constructs. (We should actually disable gcc C99 syntax options if we are serious about portability.) --- src/gallium/auxiliary/cso_cache/cso_hash.c | 35 ++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index 0338cb3b47..b40217c524 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -158,11 +158,14 @@ static void cso_data_rehash(struct cso_hash_data *hash, int hint) while (firstNode != e) { unsigned h = firstNode->key; struct cso_node *lastNode = firstNode; + struct cso_node *afterLastNode; + struct cso_node **beforeFirstNode; + while (lastNode->next != e && lastNode->next->key == h) lastNode = lastNode->next; - struct cso_node *afterLastNode = lastNode->next; - struct cso_node **beforeFirstNode = &hash->buckets[h % hash->numBuckets]; + afterLastNode = lastNode->next; + beforeFirstNode = &hash->buckets[h % hash->numBuckets]; while (*beforeFirstNode != e) beforeFirstNode = &(*beforeFirstNode)->next; lastNode->next = *beforeFirstNode; @@ -222,10 +225,12 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, { cso_data_might_grow(hash->data.d); - struct cso_node **nextNode = cso_hash_find_node(hash, key); - struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); - struct cso_hash_iter iter = {hash, node}; - return iter; + { + struct cso_node **nextNode = cso_hash_find_node(hash, key); + struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); + struct cso_hash_iter iter = {hash, node}; + return iter; + } } struct cso_hash * cso_hash_create(void) @@ -290,6 +295,10 @@ static struct cso_node *cso_hash_data_next(struct cso_node *node) struct cso_node *e; struct cso_hash_data *d; } a; + int start; + struct cso_node **bucket; + int n; + a.next = node->next; if (!a.next) { fprintf(stderr, "iterating beyond the last element\n"); @@ -298,9 +307,9 @@ static struct cso_node *cso_hash_data_next(struct cso_node *node) if (a.next->next) return a.next; - int start = (node->key % a.d->numBuckets) + 1; - struct cso_node **bucket = a.d->buckets + start; - int n = a.d->numBuckets - start; + start = (node->key % a.d->numBuckets) + 1; + bucket = a.d->buckets + start; + n = a.d->numBuckets - start; while (n--) { if (*bucket != a.e) return *bucket; @@ -316,19 +325,21 @@ static struct cso_node *cso_hash_data_prev(struct cso_node *node) struct cso_node *e; struct cso_hash_data *d; } a; + int start; + struct cso_node *sentinel; + struct cso_node **bucket; a.e = node; while (a.e->next) a.e = a.e->next; - int start; if (node == a.e) start = a.d->numBuckets - 1; else start = node->key % a.d->numBuckets; - struct cso_node *sentinel = node; - struct cso_node **bucket = a.d->buckets + start; + sentinel = node; + bucket = a.d->buckets + start; while (start >= 0) { if (*bucket != sentinel) { struct cso_node *prev = *bucket; -- cgit v1.2.3 From 5480a6bc13a555f99a89fc801cfe153182697dda Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 18:57:25 +0900 Subject: Fix windows build. --- src/gallium/auxiliary/rtasm/rtasm_execmem.c | 3 ++- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 2 +- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index 9c78fa5626..300c1c2d9d 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -33,6 +33,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" +#include "pipe/p_util.h" #include "rtasm_execmem.h" @@ -118,7 +119,7 @@ rtasm_exec_free(void *addr) */ void * -rtasm_exec_malloc(GLuint size) +rtasm_exec_malloc(size_t size) { return MALLOC( size ); } diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index b332192a62..dcbf76f600 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -21,7 +21,7 @@ * **************************************************************************/ -#if defined(__i386__) || defined(__386__) +#if defined(__i386__) || defined(__386__) || defined(i386) #include "pipe/p_compiler.h" #include "pipe/p_debug.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index e4576001bf..606b41eb35 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -24,7 +24,7 @@ #ifndef _RTASM_X86SSE_H_ #define _RTASM_X86SSE_H_ -#if defined(__i386__) || defined(__386__) +#if defined(__i386__) || defined(__386__) || defined(i386) /* It is up to the caller to ensure that instructions issued are * suitable for the host cpu. There are no checks made in this module -- cgit v1.2.3 From 4362c6e59d575a039e654e1520bbff89b73fc8f2 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 18 Feb 2008 18:51:57 -0800 Subject: Cell: trivial clean-ups --- src/gallium/drivers/cell/spu/spu_exec.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 109540b1f7..0eb5ea1a3f 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -146,17 +146,13 @@ spu_exec_machine_init(struct spu_exec_machine *mach, struct spu_sampler *samplers, unsigned processor) { - qword zero; - qword not_zero; - uint i; + const qword zero = si_il(0); + const qword not_zero = si_il(~0); mach->Samplers = samplers; mach->Processor = processor; mach->Addrs = &mach->Temps[TGSI_EXEC_NUM_TEMPS]; - zero = si_xor(zero, zero); - not_zero = si_xori(zero, 0xff); - /* Setup constants. */ mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].q = zero; mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].q = not_zero; -- cgit v1.2.3 From 66be2810c3be07dd1ee45a60cfc632725837f2cd Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 18 Feb 2008 18:55:39 -0800 Subject: Cell: emit vertex shaders and uniforms more intelligently --- src/gallium/drivers/cell/common.h | 22 ++++---- src/gallium/drivers/cell/ppu/cell_state_emit.c | 18 ++++++ src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 17 +++--- src/gallium/drivers/cell/spu/spu_main.c | 9 +++ src/gallium/drivers/cell/spu/spu_vertex_fetch.c | 6 +- src/gallium/drivers/cell/spu/spu_vertex_shader.c | 68 ++++++++++------------- src/gallium/drivers/cell/spu/spu_vertex_shader.h | 5 ++ 7 files changed, 85 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index 74b131fbef..cf892206c6 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -87,10 +87,12 @@ #define CELL_CMD_STATE_TEXTURE 13 #define CELL_CMD_STATE_VERTEX_INFO 14 #define CELL_CMD_STATE_VIEWPORT 15 -#define CELL_CMD_STATE_VS_ARRAY_INFO 16 -#define CELL_CMD_STATE_BLEND 17 -#define CELL_CMD_VS_EXECUTE 18 -#define CELL_CMD_STATE_ATTRIB_FETCH 19 +#define CELL_CMD_STATE_UNIFORMS 16 +#define CELL_CMD_STATE_VS_ARRAY_INFO 17 +#define CELL_CMD_STATE_BIND_VS 18 +#define CELL_CMD_STATE_BLEND 19 +#define CELL_CMD_STATE_ATTRIB_FETCH 20 +#define CELL_CMD_VS_EXECUTE 21 #define CELL_NUM_BUFFERS 4 @@ -144,14 +146,13 @@ struct cell_attribute_fetch_code { struct cell_shader_info { - unsigned num_outputs; - uint64_t declarations; - unsigned num_declarations; uint64_t instructions; - unsigned num_instructions; - uint64_t uniforms; uint64_t immediates; + + unsigned num_outputs; + unsigned num_declarations; + unsigned num_instructions; unsigned num_immediates; } ALIGN16_ATTRIB; @@ -160,10 +161,9 @@ struct cell_shader_info struct cell_command_vs { uint64_t opcode; /**< CELL_CMD_VS_EXECUTE */ - struct cell_shader_info shader; + uint64_t vOut[SPU_VERTS_PER_BATCH]; unsigned num_elts; unsigned elts[SPU_VERTS_PER_BATCH]; - uint64_t vOut[SPU_VERTS_PER_BATCH]; float plane[12][4]; unsigned nr_planes; unsigned nr_attrs; diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 5d2a786449..49c0d130c5 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -31,6 +31,8 @@ #include "cell_state_emit.h" #include "cell_batch.h" #include "cell_texture.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" static void @@ -100,4 +102,20 @@ cell_emit_state(struct cell_context *cell) emit_state_cmd(cell, CELL_CMD_STATE_VERTEX_INFO, &cell->vertex_info, sizeof(struct vertex_info)); } + + if (cell->dirty & CELL_NEW_VS) { + const struct draw_context *const draw = cell->draw; + struct cell_shader_info info; + + info.num_outputs = draw->num_vs_outputs; + info.declarations = (uintptr_t) draw->machine.Declarations; + info.num_declarations = draw->machine.NumDeclarations; + info.instructions = (uintptr_t) draw->machine.Instructions; + info.num_instructions = draw->machine.NumInstructions; + info.immediates = (uintptr_t) draw->machine.Imms; + info.num_immediates = draw->machine.ImmLimit / 4; + + emit_state_cmd(cell, CELL_CMD_STATE_BIND_VS, + & info, sizeof(info)); + } } diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 6a1d3bc20a..64c7821c19 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -54,6 +54,7 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) struct cell_command_vs *const vs = &cell_global.command[0].vs; uint64_t *batch; struct cell_array_info *array_info; + struct cell_shader_info *shader_info; unsigned i, j; struct cell_attribute_fetch_code *cf; @@ -100,17 +101,17 @@ cell_vertex_shader_queue_flush(struct draw_context *draw) (void) memcpy(&batch[1], &draw->viewport, sizeof(struct pipe_viewport_state)); + { + uint64_t uniforms = (uintptr_t) draw->user.constants; + + batch = cell_batch_alloc(cell, 2 *sizeof(batch[0])); + batch[0] = CELL_CMD_STATE_UNIFORMS; + batch[1] = uniforms; + } + cell_batch_flush(cell); vs->opcode = CELL_CMD_VS_EXECUTE; - vs->shader.num_outputs = draw->num_vs_outputs; - vs->shader.declarations = (uintptr_t) draw->machine.Declarations; - vs->shader.num_declarations = draw->machine.NumDeclarations; - vs->shader.instructions = (uintptr_t) draw->machine.Instructions; - vs->shader.num_instructions = draw->machine.NumInstructions; - vs->shader.uniforms = (uintptr_t) draw->user.constants; - vs->shader.immediates = (uintptr_t) draw->machine.Imms; - vs->shader.num_immediates = draw->machine.ImmLimit / 4; vs->nr_attrs = draw->vertex_fetch.nr_attrs; (void) memcpy(vs->plane, draw->plane, sizeof(draw->plane)); diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index fcbf0f841e..dbc3705c24 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -433,10 +433,19 @@ cmd_batch(uint opcode) sizeof(struct pipe_viewport_state)); pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8); break; + case CELL_CMD_STATE_UNIFORMS: + draw.constants = (float (*)[4]) (uintptr_t) buffer[pos + 1]; + pos += 2; + break; case CELL_CMD_STATE_VS_ARRAY_INFO: cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]); pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8); break; + case CELL_CMD_STATE_BIND_VS: + spu_bind_vertex_shader(&draw, + (struct cell_shader_info *) &buffer[pos+1]); + pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8); + break; case CELL_CMD_STATE_ATTRIB_FETCH: { struct cell_attribute_fetch_code *code = (struct cell_attribute_fetch_code *) &buffer[pos+1]; diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c index 55c6c28717..e5d9910ff3 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -64,7 +64,7 @@ typedef void (*spu_fetch_func)(qword *out, const qword *in, const qword *shuffle_data); -static const qword fetch_shuffle_data[] = { +static const qword fetch_shuffle_data[5] ALIGN16_ATTRIB = { /* Shuffle used by CVT_64_FLOAT */ { @@ -108,7 +108,7 @@ static const qword fetch_shuffle_data[] = { static INLINE void fetch_unaligned(qword *dst, unsigned ea, unsigned size) { - qword tmp[4]; + qword tmp[4] ALIGN16_ATTRIB; const int shift = ea & 0x0f; const unsigned aligned_start_ea = ea & ~0x0f; const unsigned aligned_end_ea = (ea + size) & ~0x0f; @@ -169,7 +169,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, unsigned idx; const unsigned bytes_per_entry = draw->vertex_fetch.size[attr]; const unsigned quads_per_entry = (bytes_per_entry + 15) / 16; - qword in[2 * 4]; + qword in[2 * 4] ALIGN16_ATTRIB; /* Fetch four attributes for four vertices. diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.c b/src/gallium/drivers/cell/spu/spu_vertex_shader.c index 3f5bf41aa2..8363efeeb6 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.c @@ -165,63 +165,55 @@ run_vertex_program(struct spu_vs_context *draw, } -static void -spu_bind_vertex_shader(struct spu_vs_context *draw, - void *uniforms, - void *planes, - unsigned nr_planes, - unsigned num_outputs - ) -{ - draw->constants = (float (*)[4]) uniforms; - - (void) memcpy(draw->plane, planes, sizeof(float) * 4 * nr_planes); - draw->nr_planes = nr_planes; - draw->num_vs_outputs = num_outputs; - - /* specify the shader to interpret/execute */ - spu_exec_machine_init(&draw->machine, - PIPE_MAX_SAMPLERS, - NULL /*samplers*/, - PIPE_SHADER_VERTEX); -} - - unsigned char immediates[(sizeof(float) * 4 * TGSI_EXEC_NUM_IMMEDIATES) + 32] ALIGN16_ATTRIB; + void -spu_execute_vertex_shader(struct spu_vs_context *draw, - const struct cell_command_vs *vs) +spu_bind_vertex_shader(struct spu_vs_context *draw, + struct cell_shader_info *vs) { - unsigned i; - - const uint64_t immediate_addr = vs->shader.immediates; + const unsigned immediate_addr = vs->immediates; const unsigned immediate_size = - ROUNDUP16((sizeof(float) * 4 * vs->shader.num_immediates) - + (immediate_addr & 0x0f)); + ROUNDUP16((sizeof(float) * 4 * vs->num_immediates) + + (immediate_addr & 0x0f)); + mfc_get(immediates, immediate_addr & ~0x0f, immediate_size, TAG_VERTEX_BUFFER, 0, 0); draw->machine.Instructions = (struct tgsi_full_instruction *) - vs->shader.instructions; - draw->machine.NumInstructions = vs->shader.num_instructions; + vs->instructions; + draw->machine.NumInstructions = vs->num_instructions; draw->machine.Declarations = (struct tgsi_full_declaration *) - vs->shader.declarations; - draw->machine.NumDeclarations = vs->shader.num_declarations; + vs->declarations; + draw->machine.NumDeclarations = vs->num_declarations; - draw->vertex_fetch.nr_attrs = vs->nr_attrs; + draw->num_vs_outputs = vs->num_outputs; + + /* specify the shader to interpret/execute */ + spu_exec_machine_init(&draw->machine, + PIPE_MAX_SAMPLERS, + NULL /*samplers*/, + PIPE_SHADER_VERTEX); wait_on_mask(1 << TAG_VERTEX_BUFFER); (void) memcpy(& draw->machine.Imms, &immediates[immediate_addr & 0x0f], - sizeof(float) * 4 * vs->shader.num_immediates); + sizeof(float) * 4 * vs->num_immediates); +} - spu_bind_vertex_shader(draw, vs->shader.uniforms, - vs->plane, vs->nr_planes, - vs->shader.num_outputs); + +void +spu_execute_vertex_shader(struct spu_vs_context *draw, + const struct cell_command_vs *vs) +{ + unsigned i; + + (void) memcpy(draw->plane, vs->plane, sizeof(float) * 4 * vs->nr_planes); + draw->nr_planes = vs->nr_planes; + draw->vertex_fetch.nr_attrs = vs->nr_attrs; for (i = 0; i < vs->num_elts; i += 4) { const unsigned batch_size = MIN2(vs->num_elts - i, 4); diff --git a/src/gallium/drivers/cell/spu/spu_vertex_shader.h b/src/gallium/drivers/cell/spu/spu_vertex_shader.h index 0fb0bc28d0..54a4b8d9b9 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_shader.h +++ b/src/gallium/drivers/cell/spu/spu_vertex_shader.h @@ -1,6 +1,7 @@ #ifndef SPU_VERTEX_SHADER_H #define SPU_VERTEX_SHADER_H +#include "cell/common.h" #include "pipe/p_format.h" #include "spu_exec.h" @@ -54,6 +55,10 @@ static INLINE void spu_vertex_fetch(struct spu_vs_context *draw, struct cell_command_vs; +extern void +spu_bind_vertex_shader(struct spu_vs_context *draw, + struct cell_shader_info *vs); + extern void spu_execute_vertex_shader(struct spu_vs_context *draw, const struct cell_command_vs *vs); -- cgit v1.2.3 From 3e329ea7e41e8d97de5b5f345ecab0833c8afe70 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 11:14:54 -0700 Subject: gallium: updated cell build Building on Ian's Cell build fix. Put libcell.a in the gallium/drivers/cell/ directory. General Makefile clean-up, simplification, updated comments. --- src/gallium/drivers/cell/ppu/Makefile | 12 ++++++++---- src/gallium/winsys/xlib/Makefile | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 196ab777f5..3c3f622a2f 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -1,6 +1,6 @@ # Gallium3D Cell driver: PPU code -# This makefile builds the g3dcell.a library which gets pulled into +# This makefile builds the libcell.a library which gets pulled into # the main libGL.so library @@ -8,10 +8,14 @@ TOP = ../../../../.. include $(TOP)/configs/linux-cell -#PROG = gl4 +# This is the "top-level" cell PPU driver code, will get pulled into libGL.so +# by the winsys Makefile. +CELL_LIB = ../libcell.a -CELL_LIB = libcell.a +# This is the SPU code. We'd like to be able to put this into the libcell.a +# archive with the PPU code, but nesting .a libs doesn't seem to work. +# So, it's pulled into libGL.so in gallium/winsys/xlib/Makefile SPU_CODE_MODULE = ../spu/g3d_spu.a @@ -56,7 +60,7 @@ default: $(CELL_LIB) $(CELL_LIB): $(OBJECTS) $(SPU_CODE_MODULE) -# ar -ru $(CELL_LIB) $(OBJECTS) $(SPU_CODE_MODULE) +# ar -ru $(CELL_LIB) $(OBJECTS) $(SPU_CODE_MODULE) # doesn't work ar -ru $(CELL_LIB) $(OBJECTS) #$(PROG): $(PPU_OBJECTS) diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 17405388ee..09f10e5ea8 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -1,4 +1,4 @@ -# src/mesa/Makefile +# src/gallium/winsys/xlib/Makefile TOP = ../../../.. include $(TOP)/configs/current @@ -27,16 +27,17 @@ GL_MINOR = 5 GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) +ifeq ($(CONFIG_NAME), linux-cell) +# The SPU code is in a separate .a file, unfortunately +CELL_SPU_LIB = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a +endif + PIPE_LIB = \ $(GALLIUM_DRIVERS) \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ - $(GALLIUM_AUXILIARIES) - -ifeq ($(CONFIG_NAME), linux-cell) -CELL_LIB = $(TOP)/src/gallium/drivers/cell/ppu/libcell.a -CELL_LIB_SPU = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a -endif + $(GALLIUM_AUXILIARIES) \ + $(CELL_SPU_LIB) \ .SUFFIXES : .cpp @@ -65,13 +66,13 @@ STAND_ALONE_OBJECTS = \ $(STAND_ALONE_DRIVER_OBJECTS) # Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(CELL_LIB) $(CELL_LIB_SPU) +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) --end-group $(CELL_LIB) $(CELL_LIB_SPU) $(GL_LIB_DEPS) + --start-group $(PIPE_LIB) --end-group $(GL_LIB_DEPS) ###################################################################### -- cgit v1.2.3 From b1c8fa5b6002296d9abe21c06d5cb81a3f70828a Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 14:55:18 -0700 Subject: gallium: implement correct sampling for RECT targets / unnormalized texcoords --- src/gallium/drivers/softpipe/sp_tex_sample.c | 168 +++++++++++++++++++++++---- 1 file changed, 143 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index c54e9d385c..ff872f360e 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -332,6 +332,61 @@ linear_texcoord(unsigned wrapMode, float s, unsigned size, } +/** + * For RECT textures / unnormalized texcoords + * Only a subset of wrap modes supported. + */ +static INLINE int +nearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) +{ + int i; + switch (wrapMode) { + case PIPE_TEX_WRAP_CLAMP: + i = ifloor(s); + return CLAMP(i, 0, size-1); + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + /* fall-through */ + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return ifloor( CLAMP(s, 0.5F, size - 0.5F) ); + default: + assert(0); + return 0; + } +} + + +/** + * For RECT textures / unnormalized texcoords. + * Only a subset of wrap modes supported. + */ +static INLINE void +linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, + int *i0, int *i1, float *a) +{ + switch (wrapMode) { + case PIPE_TEX_WRAP_CLAMP: + /* Not exactly what the spec says, but it matches NVIDIA output */ + s = CLAMP(s - 0.5F, 0.0, size - 1.0); + *i0 = ifloor(s); + *i1 = *i0 + 1; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + /* fall-through */ + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + s = CLAMP(s, 0.5F, size - 0.5F); + s -= 0.5F; + *i0 = ifloor(s); + *i1 = *i0 + 1; + if (*i1 > size - 1) + *i1 = size - 1; + break; + default: + assert(0); + } + *a = FRAC(s); +} + + static unsigned choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) { @@ -415,15 +470,15 @@ compute_lambda(struct tgsi_sampler *sampler, { float rho, lambda; + assert(sampler->state->normalized_coords); + assert(s); { float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; dsdx = FABSF(dsdx); dsdy = FABSF(dsdy); - rho = MAX2(dsdx, dsdy); - if (sampler->state->normalized_coords) - rho *= sampler->texture->width[0]; + rho = MAX2(dsdx, dsdy) * sampler->texture->width[0]; } if (t) { float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; @@ -431,9 +486,7 @@ compute_lambda(struct tgsi_sampler *sampler, float max; dtdx = FABSF(dtdx); dtdy = FABSF(dtdy); - max = MAX2(dtdx, dtdy); - if (sampler->state->normalized_coords) - max *= sampler->texture->height[0]; + max = MAX2(dtdx, dtdy) * sampler->texture->height[0]; rho = MAX2(rho, max); } if (p) { @@ -442,9 +495,7 @@ compute_lambda(struct tgsi_sampler *sampler, float max; dpdx = FABSF(dpdx); dpdy = FABSF(dpdy); - max = MAX2(dpdx, dpdy); - if (sampler->state->normalized_coords) - max *= sampler->texture->depth[0]; + max = MAX2(dpdx, dpdy) * sampler->texture->depth[0]; rho = MAX2(rho, max); } @@ -628,13 +679,10 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler, choose_mipmap_levels(sampler, s, t, p, lodbias, &level0, &level1, &levelBlend, &imgFilter); - if (sampler->state->normalized_coords) { - width = sampler->texture->width[level0]; - height = sampler->texture->height[level0]; - } - else { - width = height = 1; - } + assert(sampler->state->normalized_coords); + + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; assert(width > 0); @@ -765,14 +813,11 @@ sp_get_samples_3d(struct tgsi_sampler *sampler, choose_mipmap_levels(sampler, s, t, p, lodbias, &level0, &level1, &levelBlend, &imgFilter); - if (sampler->state->normalized_coords) { - width = sampler->texture->width[level0]; - height = sampler->texture->height[level0]; - depth = sampler->texture->depth[level0]; - } - else { - width = height = depth = 1; - } + assert(sampler->state->normalized_coords); + + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; + depth = sampler->texture->depth[level0]; assert(width > 0); assert(height > 0); @@ -889,6 +934,73 @@ sp_get_samples_cube(struct tgsi_sampler *sampler, } +static void +sp_get_samples_rect(struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + //sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces); + static const uint face = 0; + const uint compare_func = sampler->state->compare_func; + unsigned level0, level1, j, imgFilter; + int width, height; + float levelBlend; + + choose_mipmap_levels(sampler, s, t, p, lodbias, + &level0, &level1, &levelBlend, &imgFilter); + + /* texture RECTS cannot be mipmapped */ + assert(level0 == level1); + + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; + + assert(width > 0); + + switch (imgFilter) { + case PIPE_TEX_FILTER_NEAREST: + for (j = 0; j < QUAD_SIZE; j++) { + int x = nearest_texcoord_unnorm(sampler->state->wrap_s, s[j], width); + int y = nearest_texcoord_unnorm(sampler->state->wrap_t, t[j], height); + get_texel(sampler, face, level0, x, y, 0, rgba, j); + if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare(compare_func, rgba, p, j); + } + } + break; + case PIPE_TEX_FILTER_LINEAR: + for (j = 0; j < QUAD_SIZE; j++) { + float tx[4][4], a, b; + int x0, y0, x1, y1, c; + linear_texcoord_unnorm(sampler->state->wrap_s, s[j], width, &x0, &x1, &a); + linear_texcoord_unnorm(sampler->state->wrap_t, t[j], height, &y0, &y1, &b); + get_texel(sampler, face, level0, x0, y0, 0, tx, 0); + get_texel(sampler, face, level0, x1, y0, 0, tx, 1); + get_texel(sampler, face, level0, x0, y1, 0, tx, 2); + get_texel(sampler, face, level0, x1, y1, 0, tx, 3); + if (sampler->state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare(compare_func, tx, p, 0); + shadow_compare(compare_func, tx, p, 1); + shadow_compare(compare_func, tx, p, 2); + shadow_compare(compare_func, tx, p, 3); + } + + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_2d(a, b, tx[c][0], tx[c][1], tx[c][2], tx[c][3]); + } + } + break; + default: + assert(0); + } +} + + + + /** * Called via tgsi_sampler::get_samples() * Use the sampler's state setting to get a filtered RGBA value @@ -914,15 +1026,21 @@ sp_get_samples(struct tgsi_sampler *sampler, switch (sampler->texture->target) { case PIPE_TEXTURE_1D: + assert(sampler->state->normalized_coords); sp_get_samples_1d(sampler, s, t, p, lodbias, rgba); break; case PIPE_TEXTURE_2D: - sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); + if (sampler->state->normalized_coords) + sp_get_samples_2d(sampler, s, t, p, lodbias, rgba); + else + sp_get_samples_rect(sampler, s, t, p, lodbias, rgba); break; case PIPE_TEXTURE_3D: + assert(sampler->state->normalized_coords); sp_get_samples_3d(sampler, s, t, p, lodbias, rgba); break; case PIPE_TEXTURE_CUBE: + assert(sampler->state->normalized_coords); sp_get_samples_cube(sampler, s, t, p, lodbias, rgba); break; default: -- cgit v1.2.3 From a2c06c5b5c8b3fb9f6d65bcd288d62e112e6a603 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 14:56:01 -0700 Subject: gallium: don't hard-code attrib slot=0 in setup_fragcoord_coeff() --- src/gallium/drivers/softpipe/sp_prim_setup.c | 41 ++++++++++++---------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index d73521ccbe..7b1e131ee1 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -476,33 +476,33 @@ static void tri_persp_coeff( struct setup_stage *setup, * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. */ static void -setup_fragcoord_coeff(struct setup_stage *setup) +setup_fragcoord_coeff(struct setup_stage *setup, uint slot) { /*X*/ - setup->coef[0].a0[0] = 0; - setup->coef[0].dadx[0] = 1.0; - setup->coef[0].dady[0] = 0.0; + setup->coef[slot].a0[0] = 0; + setup->coef[slot].dadx[0] = 1.0; + setup->coef[slot].dady[0] = 0.0; /*Y*/ if (setup->softpipe->rasterizer->origin_lower_left) { /* y=0=bottom */ const int winHeight = setup->softpipe->framebuffer.cbufs[0]->height; - setup->coef[0].a0[1] = (float) (winHeight - 1); - setup->coef[0].dady[1] = -1.0; + setup->coef[slot].a0[1] = (float) (winHeight - 1); + setup->coef[slot].dady[1] = -1.0; } else { /* y=0=top */ - setup->coef[0].a0[1] = 0.0; - setup->coef[0].dady[1] = 1.0; + setup->coef[slot].a0[1] = 0.0; + setup->coef[slot].dady[1] = 1.0; } - setup->coef[0].dadx[1] = 0.0; + setup->coef[slot].dadx[1] = 0.0; /*Z*/ - setup->coef[0].a0[2] = setup->posCoef.a0[2]; - setup->coef[0].dadx[2] = setup->posCoef.dadx[2]; - setup->coef[0].dady[2] = setup->posCoef.dady[2]; + setup->coef[slot].a0[2] = setup->posCoef.a0[2]; + setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; + setup->coef[slot].dady[2] = setup->posCoef.dady[2]; /*W*/ - setup->coef[0].a0[3] = setup->posCoef.a0[3]; - setup->coef[0].dadx[3] = setup->posCoef.dadx[3]; - setup->coef[0].dady[3] = setup->posCoef.dady[3]; + setup->coef[slot].a0[3] = setup->posCoef.a0[3]; + setup->coef[slot].dadx[3] = setup->posCoef.dadx[3]; + setup->coef[slot].dady[3] = setup->posCoef.dady[3]; } @@ -543,8 +543,7 @@ static void setup_tri_coefficients( struct setup_stage *setup ) tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_POS: - assert(fragSlot == 0); - setup_fragcoord_coeff(setup); + setup_fragcoord_coeff(setup, fragSlot); break; default: assert(0); @@ -798,9 +797,7 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_POS: - assert(fragSlot == 0); - assert(0); /* XXX fix this: */ - setup_fragcoord_coeff(setup); + setup_fragcoord_coeff(setup, fragSlot); break; default: assert(0); @@ -1022,9 +1019,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim) &setup->coef[fragSlot], vertSlot, j); break; case INTERP_POS: - assert(fragSlot == 0); - assert(0); /* XXX fix this: */ - setup_fragcoord_coeff(setup); + setup_fragcoord_coeff(setup, fragSlot); break; default: assert(0); -- cgit v1.2.3 From 4ec46e4869b60b60c7ddf43168604713b5c4c359 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 14:58:23 -0700 Subject: gallium: add some casts to prevent likely msvc warnings --- src/gallium/drivers/softpipe/sp_tex_sample.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index ff872f360e..43d5085895 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -347,7 +347,7 @@ nearest_texcoord_unnorm(unsigned wrapMode, float s, unsigned size) case PIPE_TEX_WRAP_CLAMP_TO_EDGE: /* fall-through */ case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - return ifloor( CLAMP(s, 0.5F, size - 0.5F) ); + return ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) ); default: assert(0); return 0; @@ -366,14 +366,14 @@ linear_texcoord_unnorm(unsigned wrapMode, float s, unsigned size, switch (wrapMode) { case PIPE_TEX_WRAP_CLAMP: /* Not exactly what the spec says, but it matches NVIDIA output */ - s = CLAMP(s - 0.5F, 0.0, size - 1.0); + s = CLAMP(s - 0.5F, 0.0, (float) size - 1.0); *i0 = ifloor(s); *i1 = *i0 + 1; break; case PIPE_TEX_WRAP_CLAMP_TO_EDGE: /* fall-through */ case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - s = CLAMP(s, 0.5F, size - 0.5F); + s = CLAMP(s, 0.5F, (float) size - 0.5F); s -= 0.5F; *i0 = ifloor(s); *i1 = *i0 + 1; -- cgit v1.2.3 From 75a4524f2c6444b27055e539da052827670b62cf Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 16:28:25 -0700 Subject: gallium: initialize the killmask register to zero before running shader This fixes mysterious missing fragments when running with SSE. --- src/gallium/drivers/softpipe/sp_fs_sse.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index b18772f4e6..53050b7823 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -124,6 +124,9 @@ fs_sse_run( struct sp_fragment_shader *base, (float)quad->x0, (float)quad->y0, machine->Temps); + /* init kill mask */ + machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0] = 0x0; + shader->func( machine->Inputs, machine->Outputs, machine->Consts, -- cgit v1.2.3 From 49c3f3b537cdad847eaa24f90d01c4b1f604f724 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Feb 2008 16:51:19 -0700 Subject: gallium: general clean-up of xlib winsys Makefile --- src/gallium/winsys/xlib/Makefile | 41 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile index 09f10e5ea8..c443330942 100644 --- a/src/gallium/winsys/xlib/Makefile +++ b/src/gallium/winsys/xlib/Makefile @@ -4,6 +4,11 @@ TOP = ../../../.. include $(TOP)/configs/current +GL_MAJOR = 1 +GL_MINOR = 5 +GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) + + INCLUDE_DIRS = \ -I$(TOP)/include \ -I$(TOP)/src/mesa \ @@ -12,7 +17,7 @@ INCLUDE_DIRS = \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/gallium/auxiliary -X11_DRIVER_SOURCES = \ +XLIB_WINSYS_SOURCES = \ glxapi.c \ fakeglx.c \ xfonts.c \ @@ -21,10 +26,7 @@ X11_DRIVER_SOURCES = \ xm_winsys_aub.c \ brw_aub.c - -GL_MAJOR = 1 -GL_MINOR = 5 -GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY) +XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o) ifeq ($(CONFIG_NAME), linux-cell) @@ -32,7 +34,7 @@ ifeq ($(CONFIG_NAME), linux-cell) CELL_SPU_LIB = $(TOP)/src/gallium/drivers/cell/spu/g3d_spu.a endif -PIPE_LIB = \ +LIBS = \ $(GALLIUM_DRIVERS) \ $(TOP)/src/mesa/libglapi.a \ $(TOP)/src/mesa/libmesa.a \ @@ -48,35 +50,20 @@ PIPE_LIB = \ .cpp.o: $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@ -.S.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ default: $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) -###################################################################### -# Stand-alone Mesa libGL and libOSMesa -STAND_ALONE_DRIVER_SOURCES = \ - $(X11_DRIVER_SOURCES) - -STAND_ALONE_DRIVER_OBJECTS = $(STAND_ALONE_DRIVER_SOURCES:.c=.o) - -STAND_ALONE_OBJECTS = \ - $(STAND_ALONE_DRIVER_OBJECTS) - -# Make the GL library -$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(PIPE_LIB) +# Make the libGL.so library +$(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) $(TOP)/bin/mklib -o $(GL_LIB) \ -linker "$(CC)" \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ - $(MKLIB_OPTIONS) $(STAND_ALONE_OBJECTS) \ - --start-group $(PIPE_LIB) --end-group $(GL_LIB_DEPS) - + $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \ + --start-group $(LIBS) --end-group $(GL_LIB_DEPS) -###################################################################### -# Generic stuff depend: $(ALL_SOURCES) @ echo "running $(MKDEP)" @@ -94,10 +81,6 @@ install: default $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ fi -## NOT INSTALLED YET: -## $(INSTALL) -d $(INSTALL_DIR)/include/GLES -## $(INSTALL) -m 644 include/GLES/*.h $(INSTALL_DIR)/include/GLES - # Emacs tags tags: -- cgit v1.2.3 From 22a0b85eaebf767f5b03bf899596e09f5cc03876 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 11:15:59 -0700 Subject: gallium: use pipe_texture_reference() in sp_tile_cache_set_texture() --- src/gallium/drivers/softpipe/sp_state_sampler.c | 2 +- src/gallium/drivers/softpipe/sp_tile_cache.c | 5 +++-- src/gallium/drivers/softpipe/sp_tile_cache.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 460adccec4..9246915e19 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -84,7 +84,7 @@ softpipe_set_sampler_texture(struct pipe_context *pipe, assert(unit < PIPE_MAX_SAMPLERS); softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ - sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture); + sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture); softpipe->dirty |= SP_NEW_TEXTURE; } diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index dde3fabc81..9ed3c5072d 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -212,14 +212,15 @@ sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc) * Specify the texture to cache. */ void -sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, +sp_tile_cache_set_texture(struct pipe_context *pipe, + struct softpipe_tile_cache *tc, struct pipe_texture *texture) { uint i; assert(!tc->surface); - tc->texture = texture; + pipe_texture_reference(pipe, &tc->texture, texture); if (tc->tex_surf_map) { pipe_surface_unmap(tc->tex_surf); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 7fd1081286..2631e29a3a 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -80,7 +80,8 @@ extern void sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc); extern void -sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, +sp_tile_cache_set_texture(struct pipe_context *pipe, + struct softpipe_tile_cache *tc, struct pipe_texture *texture); extern void -- cgit v1.2.3 From 58edb0683db45c449b219988a8715cf8fd69e42d Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 11:20:25 -0700 Subject: gallium: state tracker didn't always notify drivers of texobj data changes Calling glTexSubImage() or glTexImage() to replace texture data didn't reliably cause pipe->set_sampler_texture() to get called so drivers didn't always get notified of new texture data. The st_texture_object->pt pointer doesn't always indicate changed data so added a dirtyData field. --- src/mesa/state_tracker/st_atom_texture.c | 18 ++++----- src/mesa/state_tracker/st_cb_drawpixels.c | 3 +- src/mesa/state_tracker/st_cb_fbo.c | 1 + src/mesa/state_tracker/st_cb_texture.c | 42 ++++---------------- src/mesa/state_tracker/st_cb_texture.h | 32 ++++++++++++++-- src/mesa/state_tracker/st_context.h | 22 +---------- src/mesa/state_tracker/st_gen_mipmap.c | 4 +- src/mesa/state_tracker/st_texture.h | 64 +++++++++++++++++++++++++++++++ 8 files changed, 115 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 2a836d630b..9fead7e314 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -34,6 +34,7 @@ #include "st_context.h" #include "st_atom.h" +#include "st_texture.h" #include "st_cb_texture.h" #include "pipe/p_context.h" @@ -53,27 +54,26 @@ update_textures(struct st_context *st) for (unit = 0; unit < st->ctx->Const.MaxTextureCoordUnits; unit++) { const GLuint su = fprog->Base.SamplerUnits[unit]; struct gl_texture_object *texObj = st->ctx->Texture.Unit[su]._Current; - struct pipe_texture *pt; + struct st_texture_object *stObj = st_texture_object(texObj); if (texObj) { GLboolean flush, retval; retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush); /* XXX retval indicates whether there's a texture border */ - - pt = st_get_texobj_texture(texObj); - } - else { - pt = NULL; } /* XXX: need to ensure that textures are unbound/removed from * this table before being deleted, otherwise the pointer * comparison below could fail. */ - if (st->state.sampler_texture[unit] != pt) { - st->state.sampler_texture[unit] = pt; - st->pipe->set_sampler_texture(st->pipe, unit, pt); + if (st->state.sampler_texture[unit] != stObj || + (stObj && stObj->dirtyData)) { + struct pipe_texture *pt = st_get_stobj_texture(stObj); + st->state.sampler_texture[unit] = stObj; + st->pipe->set_sampler_texture(st->pipe, unit, pt); + if (stObj) + stObj->dirtyData = GL_FALSE; } } } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index e2d4e06da1..585cae3743 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -726,7 +726,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, pipe->bind_rasterizer_state(pipe, ctx->st->state.rasterizer->data); pipe->bind_fs_state(pipe, ctx->st->state.fs->data); pipe->bind_vs_state(pipe, ctx->st->state.vs->cso->data); - pipe->set_sampler_texture(pipe, unit, ctx->st->state.sampler_texture[unit]); + pipe->set_sampler_texture(pipe, unit, + st_get_stobj_texture(ctx->st->state.sampler_texture[unit])); pipe->bind_sampler_state(pipe, unit, ctx->st->state.sampler[unit]->data); pipe->set_viewport_state(pipe, &ctx->st->state.viewport); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 4341623267..781425b546 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -48,6 +48,7 @@ #include "st_cb_texture.h" #include "st_format.h" #include "st_public.h" +#include "st_texture.h" diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 03dbb30b0f..7226b0dd98 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -53,33 +53,6 @@ #define DBG if (0) printf -struct st_texture_object -{ - struct gl_texture_object base; /* The "parent" object */ - - /* The texture must include at levels [0..lastLevel] once validated: - */ - GLuint lastLevel; - - /* On validation any active images held in main memory or in other - * textures will be copied to this texture and the old storage freed. - */ - struct pipe_texture *pt; - - GLboolean imageOverride; - GLint depthOverride; - GLuint pitchOverride; -}; - - - -static INLINE struct st_texture_object * -st_texture_object(struct gl_texture_object *obj) -{ - return (struct st_texture_object *) obj; -} - - static INLINE struct st_texture_image * st_texture_image(struct gl_texture_image *img) { @@ -87,14 +60,6 @@ st_texture_image(struct gl_texture_image *img) } -struct pipe_texture * -st_get_texobj_texture(struct gl_texture_object *texObj) -{ - struct st_texture_object *stObj = st_texture_object(texObj); - return stObj->pt; -} - - static enum pipe_texture_target gl_target_to_pipe(GLenum target) { @@ -725,6 +690,9 @@ st_TexImage(GLcontext * ctx, texImage->Data = NULL; } + /* flag data as dirty */ + stObj->dirtyData = GL_TRUE; + #if 01 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { ctx->Driver.GenerateMipmap(ctx, target, texObj); @@ -900,6 +868,7 @@ st_TexSubimage(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { + struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); GLuint dstRowStride; GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, @@ -961,6 +930,9 @@ st_TexSubimage(GLcontext * ctx, st_texture_image_unmap(stImage); texImage->Data = NULL; } + + /* flag data as dirty */ + stObj->dirtyData = GL_TRUE; } diff --git a/src/mesa/state_tracker/st_cb_texture.h b/src/mesa/state_tracker/st_cb_texture.h index 878256ec26..843745fcd6 100644 --- a/src/mesa/state_tracker/st_cb_texture.h +++ b/src/mesa/state_tracker/st_cb_texture.h @@ -1,9 +1,33 @@ -#ifndef ST_CB_TEXTURE_H -#define ST_CB_TEXTURE_H +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ -extern struct pipe_texture * -st_get_texobj_texture(struct gl_texture_object *texObj); +#ifndef ST_CB_TEXTURE_H +#define ST_CB_TEXTURE_H extern GLboolean diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 59d1590f05..5be4769be4 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -59,26 +59,6 @@ struct st_tracked_state { -struct st_texture_image -{ - struct gl_texture_image base; - - /* These aren't stored in gl_texture_image - */ - GLuint level; - GLuint face; - - /* If stImage->pt != NULL, image data is stored here. - * Else if stImage->base.Data != NULL, image is stored there. - * Else there is no image data. - */ - struct pipe_texture *pt; - - struct pipe_surface *surface; -}; - - - struct st_context { GLcontext *ctx; @@ -106,7 +86,7 @@ struct st_context struct pipe_clip_state clip; struct pipe_constant_buffer constants[2]; struct pipe_framebuffer_state framebuffer; - struct pipe_texture *sampler_texture[PIPE_MAX_SAMPLERS]; + struct st_texture_object *sampler_texture[PIPE_MAX_SAMPLERS]; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 6c09b86033..a0b4b973aa 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -43,6 +43,7 @@ #include "st_draw.h" #include "st_gen_mipmap.h" #include "st_program.h" +#include "st_texture.h" #include "st_cb_drawpixels.h" #include "st_cb_texture.h" @@ -302,7 +303,8 @@ st_render_mipmap(struct st_context *st, pipe->bind_vs_state(pipe, st->state.vs->cso->data); if (st->state.sampler[0]) pipe->bind_sampler_state(pipe, 0, st->state.sampler[0]->data); - pipe->set_sampler_texture(pipe, 0, st->state.sampler_texture[0]); + pipe->set_sampler_texture(pipe, 0, + st_get_stobj_texture(st->state.sampler_texture[0])); pipe->set_viewport_state(pipe, &st->state.viewport); return TRUE; diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 72324cd9ab..78f5f451ed 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -35,6 +35,70 @@ struct pipe_context; struct pipe_texture; +struct st_texture_image +{ + struct gl_texture_image base; + + /* These aren't stored in gl_texture_image + */ + GLuint level; + GLuint face; + + /* If stImage->pt != NULL, image data is stored here. + * Else if stImage->base.Data != NULL, image is stored there. + * Else there is no image data. + */ + struct pipe_texture *pt; + + struct pipe_surface *surface; +}; + + + +struct st_texture_object +{ + struct gl_texture_object base; /* The "parent" object */ + + /* The texture must include at levels [0..lastLevel] once validated: + */ + GLuint lastLevel; + + /* On validation any active images held in main memory or in other + * textures will be copied to this texture and the old storage freed. + */ + struct pipe_texture *pt; + + GLboolean imageOverride; + GLint depthOverride; + GLuint pitchOverride; + + GLboolean dirtyData; +}; + + +static INLINE struct st_texture_object * +st_texture_object(struct gl_texture_object *obj) +{ + return (struct st_texture_object *) obj; +} + + +static INLINE struct pipe_texture * +st_get_texobj_texture(struct gl_texture_object *texObj) +{ + struct st_texture_object *stObj = st_texture_object(texObj); + return stObj ? stObj->pt : NULL; +} + + +static INLINE struct pipe_texture * +st_get_stobj_texture(struct st_texture_object *stObj) +{ + return stObj ? stObj->pt : NULL; +} + + + extern struct pipe_texture * st_texture_create(struct st_context *st, enum pipe_texture_target target, -- cgit v1.2.3 From 3ccbaa977f96eaa849093875dd0944f744ee1e21 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 13:11:51 -0700 Subject: gallium: re-enable GenerateMipmap calls --- src/mesa/state_tracker/st_cb_texture.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 7226b0dd98..2e7d78e582 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -693,11 +693,9 @@ st_TexImage(GLcontext * ctx, /* flag data as dirty */ stObj->dirtyData = GL_TRUE; -#if 01 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { ctx->Driver.GenerateMipmap(ctx, target, texObj); } -#endif } @@ -915,14 +913,9 @@ st_TexSubimage(GLcontext * ctx, } } -#if 0 - /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); + ctx->Driver.GenerateMipmap(ctx, target, texObj); } -#endif _mesa_unmap_teximage_pbo(ctx, packing); @@ -1184,17 +1177,9 @@ do_copy_texsubimage(GLcontext *ctx, pipe_surface_reference(&dest_surface, NULL); -#if 0 - /* GL_SGIS_generate_mipmap -- this can be accelerated now. - * XXX Add a ctx->Driver.GenerateMipmaps() function? - */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); + ctx->Driver.GenerateMipmap(ctx, target, texObj); } -#endif - } -- cgit v1.2.3 From 1d45787d4a70c55e7fa899d13b9139430e2fa3e2 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 13:12:36 -0700 Subject: gallium: mark texture object data dirty in do_copy_texsubimage() --- src/mesa/state_tracker/st_cb_texture.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 2e7d78e582..778fb536bc 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1091,6 +1091,7 @@ do_copy_texsubimage(GLcontext *ctx, struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level); struct st_texture_image *stImage = st_texture_image(texImage); + struct st_texture_object *stObj = st_texture_object(texObj); GLenum baseFormat = texImage->InternalFormat; struct gl_framebuffer *fb = ctx->ReadBuffer; struct st_renderbuffer *strb; @@ -1177,6 +1178,9 @@ do_copy_texsubimage(GLcontext *ctx, pipe_surface_reference(&dest_surface, NULL); + /* flag data as dirty */ + stObj->dirtyData = GL_TRUE; + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { ctx->Driver.GenerateMipmap(ctx, target, texObj); } -- cgit v1.2.3 From d5640a2dbdc4454d0405f2cd5b18fc49b1ca7694 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 13:24:52 -0700 Subject: gallium: new pipe->texture_update() function Called whenever texture data is changed (glTexImage, glTexSubImage, glCopyTexSubImage, etc). --- src/gallium/drivers/cell/ppu/cell_context.c | 1 + src/gallium/drivers/cell/ppu/cell_texture.c | 8 +++++ src/gallium/drivers/cell/ppu/cell_texture.h | 3 ++ src/gallium/drivers/failover/fo_context.c | 9 +++-- src/gallium/drivers/i915simple/i915_context.c | 1 + src/gallium/drivers/i915simple/i915_texture.c | 7 ++++ src/gallium/drivers/i915simple/i915_texture.h | 4 +++ src/gallium/drivers/i965simple/brw_context.c | 1 + src/gallium/drivers/i965simple/brw_tex_layout.c | 8 +++++ src/gallium/drivers/i965simple/brw_tex_layout.h | 3 ++ src/gallium/drivers/softpipe/sp_context.c | 1 + src/gallium/drivers/softpipe/sp_texture.c | 15 +++++++++ src/gallium/drivers/softpipe/sp_texture.h | 4 +++ src/gallium/drivers/softpipe/sp_tile_cache.c | 45 ++++++++++++++----------- src/gallium/include/pipe/p_context.h | 8 +++++ src/mesa/state_tracker/st_atom_texture.c | 14 +++++--- 16 files changed, 104 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index e1eb22f468..b6ba14578c 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -244,6 +244,7 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) /* textures */ cell->pipe.texture_create = cell_texture_create; cell->pipe.texture_release = cell_texture_release; + cell->pipe.texture_update = cell_texture_update; cell->pipe.get_tex_surface = cell_get_tex_surface; cell->pipe.set_sampler_texture = cell_set_sampler_texture; diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index c8ef36002f..4629eb1320 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -128,6 +128,14 @@ cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } +void +cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +{ + /* XXX TO DO: re-tile the texture data ... */ + +} + + /** * Called via pipe->get_tex_surface() */ diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index 0264fed88e..07e81582f4 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -67,6 +67,9 @@ cell_texture_create(struct pipe_context *pipe, extern void cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +extern void +cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); + extern struct pipe_surface * cell_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 7ce4a7df17..156f7399b0 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -137,15 +137,14 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover_init_state_functions( failover ); -#if 0 - failover->pipe.surface_alloc = hw->surface_alloc; -#endif - failover->pipe.get_tex_surface = hw->get_tex_surface; - failover->pipe.surface_copy = hw->surface_copy; failover->pipe.surface_fill = hw->surface_fill; + failover->pipe.texture_create = hw->texture_create; failover->pipe.texture_release = hw->texture_release; + failover->pipe.texture_update = hw->texture_update; + failover->pipe.get_tex_surface = hw->get_tex_surface; + failover->pipe.flush = hw->flush; failover->dirty = 0; diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 7f71f8fd4f..97773f1256 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -302,6 +302,7 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915->pipe.texture_create = i915_texture_create; i915->pipe.texture_release = i915_texture_release; + i915->pipe.texture_update = i915_texture_update; i915->dirty = ~0; i915->hardware_dirty = ~0; diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 6d37ae3d74..4ba76d19ad 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -534,3 +534,10 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } *pt = NULL; } + + +void +i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +{ + /* no-op? */ +} diff --git a/src/gallium/drivers/i915simple/i915_texture.h b/src/gallium/drivers/i915simple/i915_texture.h index 330d111dc7..0312977552 100644 --- a/src/gallium/drivers/i915simple/i915_texture.h +++ b/src/gallium/drivers/i915simple/i915_texture.h @@ -14,4 +14,8 @@ extern void i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +extern void +i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); + + #endif /* I915_TEXTURE_H */ diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index 5e58701e91..2e2380a8d6 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -224,6 +224,7 @@ struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys, brw->pipe.clear = brw_clear; brw->pipe.texture_create = brw_texture_create; brw->pipe.texture_release = brw_texture_release; + brw->pipe.texture_update = brw_texture_update; brw_init_surface_functions(brw); brw_init_state_functions(brw); diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 90561f1307..220591da9a 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -351,3 +351,11 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } *pt = NULL; } + + +void +brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) +{ + /* no-op? */ +} + diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.h b/src/gallium/drivers/i965simple/brw_tex_layout.h index cfd6b1ef3a..7d118d0fa8 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.h +++ b/src/gallium/drivers/i965simple/brw_tex_layout.h @@ -12,4 +12,7 @@ brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat extern void brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +extern void +brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); + #endif diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 254c6adca4..316020cba6 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -283,6 +283,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, /* textures */ softpipe->pipe.texture_create = softpipe_texture_create; softpipe->pipe.texture_release = softpipe_texture_release; + softpipe->pipe.texture_update = softpipe_texture_update; softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; /* diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 6de7a9b543..8f31f05e47 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -39,6 +39,7 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_texture.h" +#include "sp_tile_cache.h" /* Simple, maximally packed layout. @@ -128,6 +129,20 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } +void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + uint unit; + for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { + if (softpipe->texture[unit] == texture) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); + } + } +} + + /** * Called via pipe->get_tex_surface() */ diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index fa646c0de9..50fc100427 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -62,6 +62,10 @@ softpipe_texture_create(struct pipe_context *pipe, extern void softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +extern void +softpipe_texture_update(struct pipe_context *pipe, + struct pipe_texture *texture); + extern struct pipe_surface * softpipe_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 9ed3c5072d..da30dd6c48 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -359,30 +359,37 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, struct pipe_surface *ps = tc->surface; int inuse = 0, pos; - if (!ps || !ps->buffer) - return; - - for (pos = 0; pos < NUM_ENTRIES; pos++) { - struct softpipe_cached_tile *tile = tc->entries + pos; - if (tile->x >= 0) { - if (tc->depth_stencil) { - pipe_put_tile_raw(pipe, ps, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, - tile->data.depth32, 0/*STRIDE*/); - } - else { - pipe_put_tile_rgba(pipe, ps, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + if (ps && ps->buffer) { + /* caching a drawing surface */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + struct softpipe_cached_tile *tile = tc->entries + pos; + if (tile->x >= 0) { + if (tc->depth_stencil) { + pipe_put_tile_raw(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); + } + else { + pipe_put_tile_rgba(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + } + tile->x = tile->y = -1; /* mark as empty */ + inuse++; } - tile->x = tile->y = -1; /* mark as empty */ - inuse++; } - } #if TILE_CLEAR_OPTIMIZATION - sp_tile_cache_flush_clear(&softpipe->pipe, tc); + sp_tile_cache_flush_clear(&softpipe->pipe, tc); #endif + } + else if (tc->texture) { + /* caching a texture, mark all entries as embpy */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].x = -1; + } + tc->tex_face = -1; + } #if 0 debug_printf("flushed tiles in use: %d\n", inuse); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 39f95695fb..036c4c8964 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -206,6 +206,14 @@ struct pipe_context { void (*texture_release)(struct pipe_context *pipe, struct pipe_texture **pt); + /** + * Called when texture data is changed. + * Note: we could pass some hints about which mip levels or cube faces + * have changed... + */ + void (*texture_update)(struct pipe_context *pipe, + struct pipe_texture *texture); + /** Get a surface which is a "view" into a texture */ struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe, struct pipe_texture *texture, diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 9fead7e314..a4ac726816 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -67,14 +67,20 @@ update_textures(struct st_context *st) * this table before being deleted, otherwise the pointer * comparison below could fail. */ - if (st->state.sampler_texture[unit] != stObj || - (stObj && stObj->dirtyData)) { + if (st->state.sampler_texture[unit] != stObj) { struct pipe_texture *pt = st_get_stobj_texture(stObj); st->state.sampler_texture[unit] = stObj; st->pipe->set_sampler_texture(st->pipe, unit, pt); - if (stObj) - stObj->dirtyData = GL_FALSE; } + + stObj = st->state.sampler_texture[unit]; + + if (stObj && stObj->dirtyData) { + struct pipe_texture *pt = st_get_stobj_texture(stObj); + st->pipe->texture_update(st->pipe, pt); + stObj->dirtyData = GL_FALSE; + } + } } -- cgit v1.2.3 From 882a4b505484a50f1ccc2cf3ae0c3a52d4ec1be3 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:00:42 -0700 Subject: gallium: minor re-org of 915 surface/texture code --- src/gallium/drivers/i915simple/i915_context.c | 4 +- src/gallium/drivers/i915simple/i915_surface.c | 45 +-------------------- src/gallium/drivers/i915simple/i915_texture.c | 58 +++++++++++++++++++++++++-- src/gallium/drivers/i915simple/i915_texture.h | 37 ++++++++++++----- 4 files changed, 84 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 97773f1256..acfa349439 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -296,13 +296,11 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915_init_state_functions(i915); i915_init_flush_functions(i915); i915_init_string_functions(i915); + i915_init_texture_functions(i915); i915->pci_id = pci_id; i915->flags.is_i945 = is_i945; - i915->pipe.texture_create = i915_texture_create; - i915->pipe.texture_release = i915_texture_release; - i915->pipe.texture_update = i915_texture_update; i915->dirty = ~0; i915->hardware_dirty = ~0; diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index 17fd27895a..f4fbedbe9b 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -36,48 +36,6 @@ #include "util/p_tile.h" -/* - * XXX note: same as code in sp_surface.c - */ -static struct pipe_surface * -i915_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct i915_texture *tex = (struct i915_texture *)pt; - struct pipe_surface *ps; - unsigned offset; /* in bytes */ - - offset = tex->level_offset[level]; - - if (pt->target == PIPE_TEXTURE_CUBE) { - offset += tex->image_offset[level][face] * pt->cpp; - } - else if (pt->target == PIPE_TEXTURE_3D) { - offset += tex->image_offset[level][zslice] * pt->cpp; - } - else { - assert(face == 0); - assert(zslice == 0); - } - - ps = pipe->winsys->surface_alloc(pipe->winsys); - if (ps) { - assert(ps->refcount); - assert(ps->winsys); - pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = tex->pitch; - ps->offset = offset; - } - return ps; -} - - - /* Assumes all values are within bounds -- no checking at this level - * do it higher up if required. */ @@ -115,6 +73,7 @@ i915_surface_copy(struct pipe_context *pipe, } } + /* Fill a rectangular sub-region. Need better logic about when to * push buffers into AGP - will currently do so whenever possible. */ @@ -184,8 +143,6 @@ i915_surface_fill(struct pipe_context *pipe, void i915_init_surface_functions(struct i915_context *i915) { - i915->pipe.get_tex_surface = i915_get_tex_surface; - i915->pipe.surface_copy = i915_surface_copy; i915->pipe.surface_fill = i915_surface_fill; } diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index 4ba76d19ad..b235fae96d 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -478,7 +478,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) } -struct pipe_texture * +static struct pipe_texture * i915_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) { @@ -506,7 +506,7 @@ i915_texture_create(struct pipe_context *pipe, } -void +static void i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) { if (!*pt) @@ -536,8 +536,60 @@ i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } -void +static void i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { /* no-op? */ } + + +/* + * XXX note: same as code in sp_surface.c + */ +static struct pipe_surface * +i915_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct i915_texture *tex = (struct i915_texture *)pt; + struct pipe_surface *ps; + unsigned offset; /* in bytes */ + + offset = tex->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += tex->image_offset[level][face] * pt->cpp; + } + else if (pt->target == PIPE_TEXTURE_3D) { + offset += tex->image_offset[level][zslice] * pt->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = tex->pitch; + ps->offset = offset; + } + return ps; +} + + + +void +i915_init_texture_functions(struct i915_context *i915) +{ + i915->pipe.texture_create = i915_texture_create; + i915->pipe.texture_release = i915_texture_release; + i915->pipe.texture_update = i915_texture_update; + i915->pipe.get_tex_surface = i915_get_tex_surface; +} diff --git a/src/gallium/drivers/i915simple/i915_texture.h b/src/gallium/drivers/i915simple/i915_texture.h index 0312977552..6d8d41178f 100644 --- a/src/gallium/drivers/i915simple/i915_texture.h +++ b/src/gallium/drivers/i915simple/i915_texture.h @@ -1,21 +1,38 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ #ifndef I915_TEXTURE_H #define I915_TEXTURE_H struct pipe_context; -struct pipe_texture; - - -struct pipe_texture * -i915_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat); - -extern void -i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); extern void -i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); +i915_init_texture_functions(struct i915_context *i915); #endif /* I915_TEXTURE_H */ -- cgit v1.2.3 From 4eae65c8e052976a130564560699e60e1a3a9cc3 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:04:05 -0700 Subject: gallium: re-org of i965 texture/surface code, functions --- src/gallium/drivers/i965simple/brw_context.c | 4 +- src/gallium/drivers/i965simple/brw_surface.c | 43 +----------------- src/gallium/drivers/i965simple/brw_tex_layout.c | 60 +++++++++++++++++++++++-- src/gallium/drivers/i965simple/brw_tex_layout.h | 10 +---- 4 files changed, 60 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index 2e2380a8d6..6fb840708e 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -222,11 +222,9 @@ struct pipe_context *brw_create(struct pipe_winsys *pipe_winsys, brw->pipe.get_param = brw_get_param; brw->pipe.get_paramf = brw_get_paramf; brw->pipe.clear = brw_clear; - brw->pipe.texture_create = brw_texture_create; - brw->pipe.texture_release = brw_texture_release; - brw->pipe.texture_update = brw_texture_update; brw_init_surface_functions(brw); + brw_init_texture_functions(brw); brw_init_state_functions(brw); brw_init_flush_functions(brw); brw_init_string_functions(brw); diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index 376a42b1a6..dc4846d39f 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -35,47 +35,6 @@ #include "util/p_tile.h" -/* - * XXX note: same as code in sp_surface.c - */ -static struct pipe_surface * -brw_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct brw_texture *tex = (struct brw_texture *)pt; - struct pipe_surface *ps; - unsigned offset; /* in bytes */ - - offset = tex->level_offset[level]; - - if (pt->target == PIPE_TEXTURE_CUBE) { - offset += tex->image_offset[level][face] * pt->cpp; - } - else if (pt->target == PIPE_TEXTURE_3D) { - offset += tex->image_offset[level][zslice] * pt->cpp; - } - else { - assert(face == 0); - assert(zslice == 0); - } - - ps = pipe->winsys->surface_alloc(pipe->winsys); - if (ps) { - assert(ps->format); - assert(ps->refcount); - pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = tex->pitch; - ps->offset = offset; - } - return ps; -} - - /* Upload data to a rectangular sub-region. Lots of choices how to do this: * * - memcpy by span to current destination @@ -201,10 +160,10 @@ brw_surface_fill(struct pipe_context *pipe, } } + void brw_init_surface_functions(struct brw_context *brw) { - brw->pipe.get_tex_surface = brw_get_tex_surface; brw->pipe.surface_copy = brw_surface_copy; brw->pipe.surface_fill = brw_surface_fill; } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 220591da9a..043a2ff9a4 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -300,8 +300,9 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture } -struct pipe_texture * -brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) +static struct pipe_texture * +brw_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat) { struct brw_texture *tex = CALLOC_STRUCT(brw_texture); @@ -323,7 +324,8 @@ brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat return &tex->base; } -void + +static void brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) { if (!*pt) @@ -353,9 +355,59 @@ brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } -void +static void brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { /* no-op? */ } + +/* + * XXX note: same as code in sp_surface.c + */ +static struct pipe_surface * +brw_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct brw_texture *tex = (struct brw_texture *)pt; + struct pipe_surface *ps; + unsigned offset; /* in bytes */ + + offset = tex->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += tex->image_offset[level][face] * pt->cpp; + } + else if (pt->target == PIPE_TEXTURE_3D) { + offset += tex->image_offset[level][zslice] * pt->cpp; + } + else { + assert(face == 0); + assert(zslice == 0); + } + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->format); + assert(ps->refcount); + pipe_buffer_reference(pipe->winsys, &ps->buffer, tex->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = tex->pitch; + ps->offset = offset; + } + return ps; +} + + +void +brw_init_texture_functions(struct brw_context *brw) +{ + brw->pipe.texture_create = brw_texture_create; + brw->pipe.texture_release = brw_texture_release; + brw->pipe.texture_update = brw_texture_update; + brw->pipe.get_tex_surface = brw_get_tex_surface; +} diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.h b/src/gallium/drivers/i965simple/brw_tex_layout.h index 7d118d0fa8..ed49baeef8 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.h +++ b/src/gallium/drivers/i965simple/brw_tex_layout.h @@ -1,18 +1,12 @@ #ifndef BRW_TEX_LAYOUT_H #define BRW_TEX_LAYOUT_H -#include "pipe/p_compiler.h" -struct pipe_context; -struct pipe_texture; +struct brw_context; -extern struct pipe_texture * -brw_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat); extern void -brw_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); +brw_init_texture_functions(struct brw_context *brw); -extern void -brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); #endif -- cgit v1.2.3 From 9171e63f414866aef155b17d3c85c9a236a872d6 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:21:45 -0700 Subject: cell: put most simple state-setter functions in new cell_pipe_state.c file Also, re-org of texture/surface functions. --- src/gallium/drivers/cell/ppu/Makefile | 6 +- src/gallium/drivers/cell/ppu/cell_context.c | 35 +-- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 323 +++++++++++++++++++++++++ src/gallium/drivers/cell/ppu/cell_pipe_state.h | 39 +++ src/gallium/drivers/cell/ppu/cell_state.h | 69 +----- src/gallium/drivers/cell/ppu/cell_texture.c | 21 +- src/gallium/drivers/cell/ppu/cell_texture.h | 20 +- 7 files changed, 389 insertions(+), 124 deletions(-) create mode 100644 src/gallium/drivers/cell/ppu/cell_pipe_state.c create mode 100644 src/gallium/drivers/cell/ppu/cell_pipe_state.h (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 3c3f622a2f..6b6dfca890 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -25,14 +25,10 @@ SOURCES = \ cell_context.c \ cell_draw_arrays.c \ cell_flush.c \ - cell_state_blend.c \ - cell_state_clip.c \ cell_state_derived.c \ cell_state_emit.c \ cell_state_fs.c \ - cell_state_rasterizer.c \ - cell_state_sampler.c \ - cell_state_surface.c \ + cell_pipe_state.c \ cell_state_vertex.c \ cell_spu.c \ cell_surface.c \ diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index b6ba14578c..9f0ecb2be8 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -48,6 +48,7 @@ #include "cell_state.h" #include "cell_surface.h" #include "cell_spu.h" +#include "cell_pipe_state.h" #include "cell_texture.h" #include "cell_vbuf.h" @@ -198,22 +199,6 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) /* state setters */ - cell->pipe.create_blend_state = cell_create_blend_state; - cell->pipe.bind_blend_state = cell_bind_blend_state; - cell->pipe.delete_blend_state = cell_delete_blend_state; - - cell->pipe.create_sampler_state = cell_create_sampler_state; - cell->pipe.bind_sampler_state = cell_bind_sampler_state; - cell->pipe.delete_sampler_state = cell_delete_sampler_state; - - cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; - cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; - cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state; - - cell->pipe.create_rasterizer_state = cell_create_rasterizer_state; - cell->pipe.bind_rasterizer_state = cell_bind_rasterizer_state; - cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state; - cell->pipe.create_fs_state = cell_create_fs_state; cell->pipe.bind_fs_state = cell_bind_fs_state; cell->pipe.delete_fs_state = cell_delete_fs_state; @@ -222,16 +207,8 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) cell->pipe.bind_vs_state = cell_bind_vs_state; cell->pipe.delete_vs_state = cell_delete_vs_state; - cell->pipe.set_blend_color = cell_set_blend_color; - cell->pipe.set_clip_state = cell_set_clip_state; cell->pipe.set_constant_buffer = cell_set_constant_buffer; - cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; - - cell->pipe.set_polygon_stipple = cell_set_polygon_stipple; - cell->pipe.set_scissor_state = cell_set_scissor_state; - cell->pipe.set_viewport_state = cell_set_viewport_state; - cell->pipe.set_vertex_buffer = cell_set_vertex_buffer; cell->pipe.set_vertex_element = cell_set_vertex_element; @@ -241,21 +218,15 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) cell->pipe.clear = cell_clear_surface; cell->pipe.flush = cell_flush; - /* textures */ - cell->pipe.texture_create = cell_texture_create; - cell->pipe.texture_release = cell_texture_release; - cell->pipe.texture_update = cell_texture_update; - cell->pipe.get_tex_surface = cell_get_tex_surface; - - cell->pipe.set_sampler_texture = cell_set_sampler_texture; - #if 0 cell->pipe.begin_query = cell_begin_query; cell->pipe.end_query = cell_end_query; cell->pipe.wait_query = cell_wait_query; #endif + cell_init_state_functions(cell); cell_init_surface_functions(cell); + cell_init_texture_functions(cell); cell->draw = cell_draw_create(cell); diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c new file mode 100644 index 0000000000..aef50725e8 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -0,0 +1,323 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: + * Keith Whitwell + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "draw/draw_context.h" +#include "cell_context.h" +#include "cell_state.h" +#include "cell_texture.h" + + + +static void * +cell_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + return mem_dup(blend, sizeof(*blend)); +} + + +static void +cell_bind_blend_state(struct pipe_context *pipe, void *blend) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->blend = (const struct pipe_blend_state *)blend; + + cell->dirty |= CELL_NEW_BLEND; +} + + +static void +cell_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + FREE(blend); +} + + +static void +cell_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *blend_color) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->blend_color = *blend_color; + + cell->dirty |= CELL_NEW_BLEND; +} + + + + +static void * +cell_create_depth_stencil_alpha_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + return mem_dup(depth_stencil, sizeof(*depth_stencil)); +} + + +static void +cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->depth_stencil + = (const struct pipe_depth_stencil_alpha_state *) depth_stencil; + + cell->dirty |= CELL_NEW_DEPTH_STENCIL; +} + + +static void +cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth) +{ + FREE(depth); +} + + +static void cell_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct cell_context *cell = cell_context(pipe); + + /* pass the clip state to the draw module */ + draw_set_clip_state(cell->draw, clip); +} + + + +/* Called when driver state tracker notices changes to the viewport + * matrix: + */ +static void +cell_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct cell_context *cell = cell_context(pipe); + + cell->viewport = *viewport; /* struct copy */ + cell->dirty |= CELL_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + draw_set_viewport_state(cell->draw, viewport); + + /* Using tnl/ and vf/ modules is temporary while getting started. + * Full pipe will have vertex shader, vertex fetch of its own. + */ +} + + +static void +cell_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct cell_context *cell = cell_context(pipe); + + memcpy( &cell->scissor, scissor, sizeof(*scissor) ); + cell->dirty |= CELL_NEW_SCISSOR; +} + + +static void +cell_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ + struct cell_context *cell = cell_context(pipe); + + memcpy( &cell->poly_stipple, stipple, sizeof(*stipple) ); + cell->dirty |= CELL_NEW_STIPPLE; +} + + + +static void * +cell_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *setup) +{ + struct pipe_rasterizer_state *state + = MALLOC(sizeof(struct pipe_rasterizer_state)); + memcpy(state, setup, sizeof(struct pipe_rasterizer_state)); + return state; +} + + +static void +cell_bind_rasterizer_state(struct pipe_context *pipe, void *setup) +{ + struct cell_context *cell = cell_context(pipe); + + /* pass-through to draw module */ + draw_set_rasterizer_state(cell->draw, setup); + + cell->rasterizer = (struct pipe_rasterizer_state *)setup; + + cell->dirty |= CELL_NEW_RASTERIZER; +} + + +static void +cell_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer) +{ + FREE(rasterizer); +} + + + +static void * +cell_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + return mem_dup(sampler, sizeof(*sampler)); +} + + +static void +cell_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + assert(unit < PIPE_MAX_SAMPLERS); + cell->sampler[unit] = (struct pipe_sampler_state *)sampler; + + cell->dirty |= CELL_NEW_SAMPLER; +} + + +static void +cell_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + FREE( sampler ); +} + + + +static void +cell_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, + struct pipe_texture *texture) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->texture[sampler] = cell_texture(texture); + + cell_update_texture_mapping(cell); + + cell->dirty |= CELL_NEW_TEXTURE; +} + + + +static void +cell_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct cell_context *cell = cell_context(pipe); + + if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) { + struct pipe_surface *csurf = fb->cbufs[0]; + struct pipe_surface *zsurf = fb->zsbuf; + uint i; + + /* unmap old surfaces */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + if (cell->framebuffer.cbufs[i] && cell->cbuf_map[i]) { + pipe_surface_unmap(cell->framebuffer.cbufs[i]); + cell->cbuf_map[i] = NULL; + } + } + + if (cell->framebuffer.zsbuf && cell->zsbuf_map) { + pipe_surface_unmap(cell->framebuffer.zsbuf); + cell->zsbuf_map = NULL; + } + + /* update my state */ + cell->framebuffer = *fb; + + /* map new surfaces */ + if (csurf) + cell->cbuf_map[0] = pipe_surface_map(csurf); + + if (zsurf) + cell->zsbuf_map = pipe_surface_map(zsurf); + + cell->dirty |= CELL_NEW_FRAMEBUFFER; + } +} + + + +void +cell_init_state_functions(struct cell_context *cell) +{ + cell->pipe.create_blend_state = cell_create_blend_state; + cell->pipe.bind_blend_state = cell_bind_blend_state; + cell->pipe.delete_blend_state = cell_delete_blend_state; + + cell->pipe.create_sampler_state = cell_create_sampler_state; + cell->pipe.bind_sampler_state = cell_bind_sampler_state; + cell->pipe.delete_sampler_state = cell_delete_sampler_state; + + cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; + cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; + cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state; + + cell->pipe.create_rasterizer_state = cell_create_rasterizer_state; + cell->pipe.bind_rasterizer_state = cell_bind_rasterizer_state; + cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state; + + cell->pipe.set_blend_color = cell_set_blend_color; + cell->pipe.set_clip_state = cell_set_clip_state; + cell->pipe.set_constant_buffer = cell_set_constant_buffer; + + cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; + + cell->pipe.set_polygon_stipple = cell_set_polygon_stipple; + cell->pipe.set_scissor_state = cell_set_scissor_state; + cell->pipe.set_viewport_state = cell_set_viewport_state; +} + diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.h b/src/gallium/drivers/cell/ppu/cell_pipe_state.h new file mode 100644 index 0000000000..1889bd52ff --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef CELL_PIPE_STATE_H +#define CELL_PIPE_STATE_H + + +struct cell_context; + +extern void +cell_init_state_functions(struct cell_context *cell); + + +#endif /* CELL_PIPE_STATE_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h index 3a71ba14fa..2af7770ebb 100644 --- a/src/gallium/drivers/cell/ppu/cell_state.h +++ b/src/gallium/drivers/cell/ppu/cell_state.h @@ -23,42 +23,6 @@ -extern void -cell_set_framebuffer_state( struct pipe_context *, - const struct pipe_framebuffer_state * ); - - - -extern void * -cell_create_blend_state(struct pipe_context *, const struct pipe_blend_state *); -extern void cell_bind_blend_state(struct pipe_context *, void *); -extern void cell_delete_blend_state(struct pipe_context *, void *); - -extern void cell_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ); - - -void * -cell_create_sampler_state(struct pipe_context *, - const struct pipe_sampler_state *); - -extern void -cell_bind_sampler_state(struct pipe_context *, unsigned, void *); - -extern void -cell_delete_sampler_state(struct pipe_context *, void *); - - -extern void * -cell_create_depth_stencil_alpha_state(struct pipe_context *, - const struct pipe_depth_stencil_alpha_state *); - -extern void -cell_bind_depth_stencil_alpha_state(struct pipe_context *, void *); - -extern void -cell_delete_depth_stencil_alpha_state(struct pipe_context *, void *); - void *cell_create_fs_state(struct pipe_context *, const struct pipe_shader_state *); @@ -69,34 +33,11 @@ void *cell_create_vs_state(struct pipe_context *, void cell_bind_vs_state(struct pipe_context *, void *); void cell_delete_vs_state(struct pipe_context *, void *); - -void * -cell_create_rasterizer_state(struct pipe_context *, - const struct pipe_rasterizer_state *); -void cell_bind_rasterizer_state(struct pipe_context *, void *); -void cell_delete_rasterizer_state(struct pipe_context *, void *); - - -void cell_set_clip_state( struct pipe_context *, - const struct pipe_clip_state * ); - -void cell_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf); - -void cell_set_polygon_stipple( struct pipe_context *, - const struct pipe_poly_stipple * ); - void -cell_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, - struct pipe_texture *texture); - -void cell_set_scissor_state( struct pipe_context *, - const struct pipe_scissor_state * ); +cell_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf); -void cell_set_texture_state( struct pipe_context *, - unsigned unit, struct pipe_texture * ); void cell_set_vertex_element(struct pipe_context *, unsigned index, @@ -106,10 +47,6 @@ void cell_set_vertex_buffer(struct pipe_context *, unsigned index, const struct pipe_vertex_buffer *); -void cell_set_viewport_state( struct pipe_context *, - const struct pipe_viewport_state * ); - - void cell_update_derived( struct cell_context *softpipe ); #endif diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index 4629eb1320..e1b91075b2 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -79,8 +79,9 @@ cell_texture_layout(struct cell_texture * spt) } -struct pipe_texture * -cell_texture_create(struct pipe_context *pipe, const struct pipe_texture *templat) +static struct pipe_texture * +cell_texture_create(struct pipe_context *pipe, + const struct pipe_texture *templat) { struct cell_texture *spt = CALLOC_STRUCT(cell_texture); if (!spt) @@ -103,7 +104,7 @@ cell_texture_create(struct pipe_context *pipe, const struct pipe_texture *templa } -void +static void cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) { if (!*pt) @@ -128,7 +129,7 @@ cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } -void +static void cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) { /* XXX TO DO: re-tile the texture data ... */ @@ -139,7 +140,7 @@ cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture) /** * Called via pipe->get_tex_surface() */ -struct pipe_surface * +static struct pipe_surface * cell_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) @@ -258,3 +259,13 @@ cell_update_texture_mapping(struct cell_context *cell) cell->tex_map = pipe_surface_map(cell->tex_surf); #endif } + + +void +cell_init_texture_functions(struct cell_context *cell) +{ + cell->pipe.texture_create = cell_texture_create; + cell->pipe.texture_release = cell_texture_release; + cell->pipe.texture_update = cell_texture_update; + cell->pipe.get_tex_surface = cell_get_tex_surface; +} diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index 07e81582f4..824fb3e20f 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -29,7 +29,7 @@ #define CELL_TEXTURE_H -struct pipe_context; +struct cell_context; struct pipe_texture; @@ -60,24 +60,12 @@ cell_texture(struct pipe_texture *pt) -extern struct pipe_texture * -cell_texture_create(struct pipe_context *pipe, - const struct pipe_texture *templat); - -extern void -cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); - extern void -cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture); - -extern struct pipe_surface * -cell_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice); +cell_update_texture_mapping(struct cell_context *cell); extern void -cell_update_texture_mapping(struct cell_context *cell); +cell_init_texture_functions(struct cell_context *cell); -#endif /* CELL_TEXTURE */ +#endif /* CELL_TEXTURE_H */ -- cgit v1.2.3 From acd2253ae80d133bc84a5e78909ec72464e3f901 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:24:46 -0700 Subject: Remove obsolete files replaced by cell_pipe_state.c --- src/gallium/drivers/cell/ppu/cell_state_blend.c | 109 --------------------- src/gallium/drivers/cell/ppu/cell_state_clip.c | 84 ---------------- .../drivers/cell/ppu/cell_state_rasterizer.c | 106 -------------------- src/gallium/drivers/cell/ppu/cell_state_sampler.c | 84 ---------------- src/gallium/drivers/cell/ppu/cell_state_surface.c | 71 -------------- 5 files changed, 454 deletions(-) delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_blend.c delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_clip.c delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_rasterizer.c delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_sampler.c delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_surface.c (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/cell_state_blend.c b/src/gallium/drivers/cell/ppu/cell_state_blend.c deleted file mode 100644 index b6d6d71f0c..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_blend.c +++ /dev/null @@ -1,109 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "cell_context.h" -#include "cell_state.h" - - - -void * -cell_create_blend_state(struct pipe_context *pipe, - const struct pipe_blend_state *blend) -{ - return mem_dup(blend, sizeof(*blend)); -} - - -void -cell_bind_blend_state(struct pipe_context *pipe, void *blend) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - cell->blend = (const struct pipe_blend_state *)blend; - - cell->dirty |= CELL_NEW_BLEND; -} - - -void -cell_delete_blend_state(struct pipe_context *pipe, void *blend) -{ - FREE(blend); -} - - -void -cell_set_blend_color(struct pipe_context *pipe, - const struct pipe_blend_color *blend_color) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - cell->blend_color = *blend_color; - - cell->dirty |= CELL_NEW_BLEND; -} - - - - -void * -cell_create_depth_stencil_alpha_state(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *depth_stencil) -{ - return mem_dup(depth_stencil, sizeof(*depth_stencil)); -} - - -void -cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe, - void *depth_stencil) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - cell->depth_stencil - = (const struct pipe_depth_stencil_alpha_state *) depth_stencil; - - cell->dirty |= CELL_NEW_DEPTH_STENCIL; -} - - -void -cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth) -{ - FREE(depth); -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_clip.c b/src/gallium/drivers/cell/ppu/cell_state_clip.c deleted file mode 100644 index 0482f87e88..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_clip.c +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: Keith Whitwell - */ - -#include "cell_context.h" -#include "cell_state.h" -#include "draw/draw_context.h" - - -void cell_set_clip_state( struct pipe_context *pipe, - const struct pipe_clip_state *clip ) -{ - struct cell_context *cell = cell_context(pipe); - - /* pass the clip state to the draw module */ - draw_set_clip_state(cell->draw, clip); -} - - - -/* Called when driver state tracker notices changes to the viewport - * matrix: - */ -void cell_set_viewport_state( struct pipe_context *pipe, - const struct pipe_viewport_state *viewport ) -{ - struct cell_context *cell = cell_context(pipe); - - cell->viewport = *viewport; /* struct copy */ - cell->dirty |= CELL_NEW_VIEWPORT; - - /* pass the viewport info to the draw module */ - draw_set_viewport_state(cell->draw, viewport); - - /* Using tnl/ and vf/ modules is temporary while getting started. - * Full pipe will have vertex shader, vertex fetch of its own. - */ -} - - -void cell_set_scissor_state( struct pipe_context *pipe, - const struct pipe_scissor_state *scissor ) -{ - struct cell_context *cell = cell_context(pipe); - - memcpy( &cell->scissor, scissor, sizeof(*scissor) ); - cell->dirty |= CELL_NEW_SCISSOR; -} - - -void cell_set_polygon_stipple( struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple ) -{ - struct cell_context *cell = cell_context(pipe); - - memcpy( &cell->poly_stipple, stipple, sizeof(*stipple) ); - cell->dirty |= CELL_NEW_STIPPLE; -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c b/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c deleted file mode 100644 index 7eca5b5765..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_rasterizer.c +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "cell_context.h" -#include "cell_state.h" - - - -struct spu_rasterizer_state -{ - unsigned flatshade:1; -#if 0 - unsigned light_twoside:1; - unsigned front_winding:2; /**< PIPE_WINDING_x */ - unsigned cull_mode:2; /**< PIPE_WINDING_x */ - unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ - unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ - unsigned offset_cw:1; - unsigned offset_ccw:1; -#endif - unsigned scissor:1; - unsigned poly_smooth:1; - unsigned poly_stipple_enable:1; - unsigned point_smooth:1; -#if 0 - unsigned point_sprite:1; - unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ -#endif - unsigned multisample:1; /* XXX maybe more ms state in future */ - unsigned line_smooth:1; - unsigned line_stipple_enable:1; - unsigned line_stipple_factor:8; /**< [1..256] actually */ - unsigned line_stipple_pattern:16; -#if 0 - unsigned bypass_clipping:1; -#endif - unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ - - float line_width; - float point_size; /**< used when no per-vertex size */ -#if 0 - float offset_units; - float offset_scale; - ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ -#endif -}; - - - -void * -cell_create_rasterizer_state(struct pipe_context *pipe, - const struct pipe_rasterizer_state *setup) -{ - struct pipe_rasterizer_state *state - = MALLOC(sizeof(struct pipe_rasterizer_state)); - memcpy(state, setup, sizeof(struct pipe_rasterizer_state)); - return state; -} - - -void -cell_bind_rasterizer_state(struct pipe_context *pipe, void *setup) -{ - struct cell_context *cell = cell_context(pipe); - - /* pass-through to draw module */ - draw_set_rasterizer_state(cell->draw, setup); - - cell->rasterizer = (struct pipe_rasterizer_state *)setup; - - cell->dirty |= CELL_NEW_RASTERIZER; -} - - -void -cell_delete_rasterizer_state(struct pipe_context *pipe, void *rasterizer) -{ - FREE(rasterizer); -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_sampler.c b/src/gallium/drivers/cell/ppu/cell_state_sampler.c deleted file mode 100644 index a33421a4ad..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_sampler.c +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Authors: - * Brian Paul - */ - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "cell_context.h" -#include "cell_state.h" -#include "cell_texture.h" - - -void * -cell_create_sampler_state(struct pipe_context *pipe, - const struct pipe_sampler_state *sampler) -{ - return mem_dup(sampler, sizeof(*sampler)); -} - -void -cell_bind_sampler_state(struct pipe_context *pipe, - unsigned unit, void *sampler) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - assert(unit < PIPE_MAX_SAMPLERS); - cell->sampler[unit] = (struct pipe_sampler_state *)sampler; - - cell->dirty |= CELL_NEW_SAMPLER; -} - - -void -cell_delete_sampler_state(struct pipe_context *pipe, - void *sampler) -{ - FREE( sampler ); -} - - - -void -cell_set_sampler_texture(struct pipe_context *pipe, - unsigned sampler, - struct pipe_texture *texture) -{ - struct cell_context *cell = cell_context(pipe); - - draw_flush(cell->draw); - - cell->texture[sampler] = texture; - - cell_update_texture_mapping(cell); - - cell->dirty |= CELL_NEW_TEXTURE; -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_surface.c b/src/gallium/drivers/cell/ppu/cell_state_surface.c deleted file mode 100644 index 287610b76b..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_surface.c +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "pipe/p_inlines.h" -#include "cell_context.h" -#include "cell_state.h" - - -void -cell_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct cell_context *cell = cell_context(pipe); - - if (1 /*memcmp(&cell->framebuffer, fb, sizeof(*fb))*/) { - struct pipe_surface *csurf = fb->cbufs[0]; - struct pipe_surface *zsurf = fb->zsbuf; - uint i; - - /* unmap old surfaces */ - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { - if (cell->framebuffer.cbufs[i] && cell->cbuf_map[i]) { - pipe_surface_unmap(cell->framebuffer.cbufs[i]); - cell->cbuf_map[i] = NULL; - } - } - - if (cell->framebuffer.zsbuf && cell->zsbuf_map) { - pipe_surface_unmap(cell->framebuffer.zsbuf); - cell->zsbuf_map = NULL; - } - - /* update my state */ - cell->framebuffer = *fb; - - /* map new surfaces */ - if (csurf) - cell->cbuf_map[0] = pipe_surface_map(csurf); - - if (zsurf) - cell->zsbuf_map = pipe_surface_map(zsurf); - - cell->dirty |= CELL_NEW_FRAMEBUFFER; - } -} - -- cgit v1.2.3 From f6e1654e22d983ec9015fe4e7445e03df1227c71 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:25:07 -0700 Subject: cell: plug in cell_set_sampler_texture --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index aef50725e8..c5ddf6a09e 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -302,6 +302,8 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.bind_sampler_state = cell_bind_sampler_state; cell->pipe.delete_sampler_state = cell_delete_sampler_state; + cell->pipe.set_sampler_texture = cell_set_sampler_texture; + cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state; cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state; cell->pipe.delete_depth_stencil_alpha_state = cell_delete_depth_stencil_alpha_state; -- cgit v1.2.3 From 9e57e70b42471ff587441fb8c1b5de728521fafd Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:27:08 -0700 Subject: cell: #includes to silence warnings --- src/gallium/drivers/cell/ppu/cell_clear.c | 1 + src/gallium/drivers/cell/ppu/cell_vertex_shader.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c index e588a30d5b..3ffe09add6 100644 --- a/src/gallium/drivers/cell/ppu/cell_clear.c +++ b/src/gallium/drivers/cell/ppu/cell_clear.c @@ -41,6 +41,7 @@ #include "cell_batch.h" #include "cell_flush.h" #include "cell_spu.h" +#include "cell_state.h" void diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index 64c7821c19..f7ef72e5a2 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -35,6 +35,7 @@ #include "cell_context.h" #include "cell_draw_arrays.h" +#include "cell_flush.h" #include "cell_spu.h" #include "cell_batch.h" -- cgit v1.2.3 From 64683473753de6eb978245e348e9b20cd1d42883 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:30:50 -0700 Subject: cell: init shader-related functions in cell_init_shader_functions() --- src/gallium/drivers/cell/ppu/cell_context.c | 11 +----- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 1 - src/gallium/drivers/cell/ppu/cell_state.h | 50 ++++++++++++++++---------- src/gallium/drivers/cell/ppu/cell_state_fs.c | 29 +++++++++++---- 4 files changed, 55 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 9f0ecb2be8..98c314f45c 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -199,16 +199,6 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) /* state setters */ - cell->pipe.create_fs_state = cell_create_fs_state; - cell->pipe.bind_fs_state = cell_bind_fs_state; - cell->pipe.delete_fs_state = cell_delete_fs_state; - - cell->pipe.create_vs_state = cell_create_vs_state; - cell->pipe.bind_vs_state = cell_bind_vs_state; - cell->pipe.delete_vs_state = cell_delete_vs_state; - - cell->pipe.set_constant_buffer = cell_set_constant_buffer; - cell->pipe.set_vertex_buffer = cell_set_vertex_buffer; cell->pipe.set_vertex_element = cell_set_vertex_element; @@ -225,6 +215,7 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) #endif cell_init_state_functions(cell); + cell_init_shader_functions(cell); cell_init_surface_functions(cell); cell_init_texture_functions(cell); diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index c5ddf6a09e..35e88f79b1 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -314,7 +314,6 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.set_blend_color = cell_set_blend_color; cell->pipe.set_clip_state = cell_set_clip_state; - cell->pipe.set_constant_buffer = cell_set_constant_buffer; cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; diff --git a/src/gallium/drivers/cell/ppu/cell_state.h b/src/gallium/drivers/cell/ppu/cell_state.h index 2af7770ebb..31ce505e21 100644 --- a/src/gallium/drivers/cell/ppu/cell_state.h +++ b/src/gallium/drivers/cell/ppu/cell_state.h @@ -1,3 +1,29 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ #ifndef CELL_STATE_H @@ -22,23 +48,6 @@ #define CELL_NEW_VERTEX_INFO 0x8000 - - -void *cell_create_fs_state(struct pipe_context *, - const struct pipe_shader_state *); -void cell_bind_fs_state(struct pipe_context *, void *); -void cell_delete_fs_state(struct pipe_context *, void *); -void *cell_create_vs_state(struct pipe_context *, - const struct pipe_shader_state *); -void cell_bind_vs_state(struct pipe_context *, void *); -void cell_delete_vs_state(struct pipe_context *, void *); - -void -cell_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf); - - void cell_set_vertex_element(struct pipe_context *, unsigned index, const struct pipe_vertex_element *); @@ -49,4 +58,9 @@ void cell_set_vertex_buffer(struct pipe_context *, void cell_update_derived( struct cell_context *softpipe ); -#endif + +void +cell_init_shader_functions(struct cell_context *cell); + +#endif /* CELL_STATE_H */ + diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_fs.c index f3958fa429..935501441b 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_fs.c +++ b/src/gallium/drivers/cell/ppu/cell_state_fs.c @@ -41,7 +41,7 @@ #include "cell_state.h" -void * +static void * cell_create_fs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { @@ -80,7 +80,7 @@ cell_create_fs_state(struct pipe_context *pipe, } -void +static void cell_bind_fs_state(struct pipe_context *pipe, void *fs) { struct cell_context *cell = cell_context(pipe); @@ -91,7 +91,7 @@ cell_bind_fs_state(struct pipe_context *pipe, void *fs) } -void +static void cell_delete_fs_state(struct pipe_context *pipe, void *fs) { struct cell_fragment_shader_state *state = @@ -101,7 +101,7 @@ cell_delete_fs_state(struct pipe_context *pipe, void *fs) } -void * +static void * cell_create_vs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) { @@ -124,7 +124,7 @@ cell_create_vs_state(struct pipe_context *pipe, } -void +static void cell_bind_vs_state(struct pipe_context *pipe, void *vs) { struct cell_context *cell = cell_context(pipe); @@ -137,7 +137,7 @@ cell_bind_vs_state(struct pipe_context *pipe, void *vs) } -void +static void cell_delete_vs_state(struct pipe_context *pipe, void *vs) { struct cell_context *cell = cell_context(pipe); @@ -150,7 +150,7 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs) } -void +static void cell_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, const struct pipe_constant_buffer *buf) @@ -169,3 +169,18 @@ cell_set_constant_buffer(struct pipe_context *pipe, cell->dirty |= CELL_NEW_CONSTANTS; } + + +void +cell_init_shader_functions(struct cell_context *cell) +{ + cell->pipe.create_fs_state = cell_create_fs_state; + cell->pipe.bind_fs_state = cell_bind_fs_state; + cell->pipe.delete_fs_state = cell_delete_fs_state; + + cell->pipe.create_vs_state = cell_create_vs_state; + cell->pipe.bind_vs_state = cell_bind_vs_state; + cell->pipe.delete_vs_state = cell_delete_vs_state; + + cell->pipe.set_constant_buffer = cell_set_constant_buffer; +} -- cgit v1.2.3 From fd4bdd020a9e1999b87d553b50151405c054a619 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:32:43 -0700 Subject: cell: rename cell_state_fs.c -> cell_state_shader.c --- src/gallium/drivers/cell/ppu/Makefile | 2 +- src/gallium/drivers/cell/ppu/cell_state_fs.c | 186 ----------------------- src/gallium/drivers/cell/ppu/cell_state_shader.c | 186 +++++++++++++++++++++++ 3 files changed, 187 insertions(+), 187 deletions(-) delete mode 100644 src/gallium/drivers/cell/ppu/cell_state_fs.c create mode 100644 src/gallium/drivers/cell/ppu/cell_state_shader.c (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index 6b6dfca890..164dde762c 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -27,7 +27,7 @@ SOURCES = \ cell_flush.c \ cell_state_derived.c \ cell_state_emit.c \ - cell_state_fs.c \ + cell_state_shader.c \ cell_pipe_state.c \ cell_state_vertex.c \ cell_spu.c \ diff --git a/src/gallium/drivers/cell/ppu/cell_state_fs.c b/src/gallium/drivers/cell/ppu/cell_state_fs.c deleted file mode 100644 index 935501441b..0000000000 --- a/src/gallium/drivers/cell/ppu/cell_state_fs.c +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "pipe/p_defines.h" -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_winsys.h" -#include "draw/draw_context.h" -#if 0 -#include "pipe/p_shader_tokens.h" -#include "gallivm/gallivm.h" -#include "tgsi/util/tgsi_dump.h" -#include "tgsi/exec/tgsi_sse2.h" -#endif - -#include "cell_context.h" -#include "cell_state.h" - - -static void * -cell_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) -{ - /*struct cell_context *cell = cell_context(pipe);*/ - struct cell_fragment_shader_state *state; - - state = CALLOC_STRUCT(cell_fragment_shader_state); - if (!state) - return NULL; - - state->shader = *templ; - -#if 0 - if (cell->dump_fs) { - tgsi_dump(state->shader.tokens, 0); - } - -#if defined(__i386__) || defined(__386__) - if (cell->use_sse) { - x86_init_func( &state->sse2_program ); - tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); - } -#endif - -#ifdef MESA_LLVM - state->llvm_prog = 0; - if (!gallivm_global_cpu_engine()) { - gallivm_cpu_engine_create(state->llvm_prog); - } - else - gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); -#endif -#endif - - return state; -} - - -static void -cell_bind_fs_state(struct pipe_context *pipe, void *fs) -{ - struct cell_context *cell = cell_context(pipe); - - cell->fs = (struct cell_fragment_shader_state *) fs; - - cell->dirty |= CELL_NEW_FS; -} - - -static void -cell_delete_fs_state(struct pipe_context *pipe, void *fs) -{ - struct cell_fragment_shader_state *state = - (struct cell_fragment_shader_state *) fs; - - FREE( state ); -} - - -static void * -cell_create_vs_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) -{ - struct cell_context *cell = cell_context(pipe); - struct cell_vertex_shader_state *state; - - state = CALLOC_STRUCT(cell_vertex_shader_state); - if (!state) - return NULL; - - state->shader = *templ; - - state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader); - if (state->draw_data == NULL) { - FREE( state ); - return NULL; - } - - return state; -} - - -static void -cell_bind_vs_state(struct pipe_context *pipe, void *vs) -{ - struct cell_context *cell = cell_context(pipe); - - cell->vs = (const struct cell_vertex_shader_state *) vs; - - draw_bind_vertex_shader(cell->draw, cell->vs->draw_data); - - cell->dirty |= CELL_NEW_VS; -} - - -static void -cell_delete_vs_state(struct pipe_context *pipe, void *vs) -{ - struct cell_context *cell = cell_context(pipe); - - struct cell_vertex_shader_state *state = - (struct cell_vertex_shader_state *) vs; - - draw_delete_vertex_shader(cell->draw, state->draw_data); - FREE( state ); -} - - -static void -cell_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf) -{ - struct cell_context *cell = cell_context(pipe); - struct pipe_winsys *ws = pipe->winsys; - - assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); - - /* note: reference counting */ - pipe_buffer_reference(ws, - &cell->constants[shader].buffer, - buf->buffer); - cell->constants[shader].size = buf->size; - - cell->dirty |= CELL_NEW_CONSTANTS; -} - - -void -cell_init_shader_functions(struct cell_context *cell) -{ - cell->pipe.create_fs_state = cell_create_fs_state; - cell->pipe.bind_fs_state = cell_bind_fs_state; - cell->pipe.delete_fs_state = cell_delete_fs_state; - - cell->pipe.create_vs_state = cell_create_vs_state; - cell->pipe.bind_vs_state = cell_bind_vs_state; - cell->pipe.delete_vs_state = cell_delete_vs_state; - - cell->pipe.set_constant_buffer = cell_set_constant_buffer; -} diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c new file mode 100644 index 0000000000..935501441b --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -0,0 +1,186 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "draw/draw_context.h" +#if 0 +#include "pipe/p_shader_tokens.h" +#include "gallivm/gallivm.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/exec/tgsi_sse2.h" +#endif + +#include "cell_context.h" +#include "cell_state.h" + + +static void * +cell_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + /*struct cell_context *cell = cell_context(pipe);*/ + struct cell_fragment_shader_state *state; + + state = CALLOC_STRUCT(cell_fragment_shader_state); + if (!state) + return NULL; + + state->shader = *templ; + +#if 0 + if (cell->dump_fs) { + tgsi_dump(state->shader.tokens, 0); + } + +#if defined(__i386__) || defined(__386__) + if (cell->use_sse) { + x86_init_func( &state->sse2_program ); + tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); + } +#endif + +#ifdef MESA_LLVM + state->llvm_prog = 0; + if (!gallivm_global_cpu_engine()) { + gallivm_cpu_engine_create(state->llvm_prog); + } + else + gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); +#endif +#endif + + return state; +} + + +static void +cell_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct cell_context *cell = cell_context(pipe); + + cell->fs = (struct cell_fragment_shader_state *) fs; + + cell->dirty |= CELL_NEW_FS; +} + + +static void +cell_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct cell_fragment_shader_state *state = + (struct cell_fragment_shader_state *) fs; + + FREE( state ); +} + + +static void * +cell_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct cell_context *cell = cell_context(pipe); + struct cell_vertex_shader_state *state; + + state = CALLOC_STRUCT(cell_vertex_shader_state); + if (!state) + return NULL; + + state->shader = *templ; + + state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader); + if (state->draw_data == NULL) { + FREE( state ); + return NULL; + } + + return state; +} + + +static void +cell_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct cell_context *cell = cell_context(pipe); + + cell->vs = (const struct cell_vertex_shader_state *) vs; + + draw_bind_vertex_shader(cell->draw, cell->vs->draw_data); + + cell->dirty |= CELL_NEW_VS; +} + + +static void +cell_delete_vs_state(struct pipe_context *pipe, void *vs) +{ + struct cell_context *cell = cell_context(pipe); + + struct cell_vertex_shader_state *state = + (struct cell_vertex_shader_state *) vs; + + draw_delete_vertex_shader(cell->draw, state->draw_data); + FREE( state ); +} + + +static void +cell_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct cell_context *cell = cell_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + /* note: reference counting */ + pipe_buffer_reference(ws, + &cell->constants[shader].buffer, + buf->buffer); + cell->constants[shader].size = buf->size; + + cell->dirty |= CELL_NEW_CONSTANTS; +} + + +void +cell_init_shader_functions(struct cell_context *cell) +{ + cell->pipe.create_fs_state = cell_create_fs_state; + cell->pipe.bind_fs_state = cell_bind_fs_state; + cell->pipe.delete_fs_state = cell_delete_fs_state; + + cell->pipe.create_vs_state = cell_create_vs_state; + cell->pipe.bind_vs_state = cell_bind_vs_state; + cell->pipe.delete_vs_state = cell_delete_vs_state; + + cell->pipe.set_constant_buffer = cell_set_constant_buffer; +} -- cgit v1.2.3 From fce61f341faf6a2e1a8497ab963985ddbffa8b0a Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 14:44:15 -0700 Subject: gallium: fix bad ptr comparison --- src/gallium/drivers/softpipe/sp_texture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 8f31f05e47..295704c05f 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -136,7 +136,7 @@ softpipe_texture_update(struct pipe_context *pipe, struct softpipe_context *softpipe = softpipe_context(pipe); uint unit; for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (softpipe->texture[unit] == texture) { + if (softpipe->texture[unit] == softpipe_texture(texture)) { sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); } } -- cgit v1.2.3 From 25ea1901b44107a5bc5351487e18d52d75df8ffd Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 15:09:27 -0700 Subject: gallium: replace some ordinary assignments with pipe_reference_texture() This fixes at least one instance of dereferencing an invalid texture pointer. --- src/gallium/drivers/cell/ppu/cell_texture.c | 1 + src/gallium/drivers/i915simple/i915_state.c | 5 ++++- src/gallium/drivers/i915simple/i915_texture.c | 1 + src/gallium/drivers/i965simple/brw_state.c | 4 +++- src/gallium/drivers/i965simple/brw_tex_layout.c | 1 + src/gallium/drivers/softpipe/sp_context.h | 2 +- src/gallium/drivers/softpipe/sp_quad_fs.c | 2 +- src/gallium/drivers/softpipe/sp_state_sampler.c | 3 ++- src/gallium/drivers/softpipe/sp_texture.c | 5 ++++- src/mesa/state_tracker/st_texture.c | 9 ++++++--- 10 files changed, 24 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index e1b91075b2..0edefa5f05 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -88,6 +88,7 @@ cell_texture_create(struct pipe_context *pipe, return NULL; spt->base = *templat; + spt->base.refcount = 1; cell_texture_layout(spt); diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 294e6fad03..e055eed7e0 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -32,6 +32,7 @@ #include "draw/draw_context.h" #include "pipe/p_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "i915_context.h" #include "i915_reg.h" @@ -505,7 +506,9 @@ static void i915_set_sampler_texture(struct pipe_context *pipe, { struct i915_context *i915 = i915_context(pipe); - i915->texture[sampler] = (struct i915_texture*)texture; /* ptr, not struct */ + pipe_texture_reference(pipe, + (struct pipe_texture **) &i915->texture[sampler], + texture); i915->dirty |= I915_NEW_TEXTURE; } diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index b235fae96d..1b415a94d4 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -488,6 +488,7 @@ i915_texture_create(struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); tex->base = *templat; + tex->base.refcount = 1; if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) : i915_miptree_layout(pipe, tex)) diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index f746d1cc57..f269b2882c 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -327,7 +327,9 @@ static void brw_set_sampler_texture(struct pipe_context *pipe, { struct brw_context *brw = brw_context(pipe); - brw->attribs.Texture[unit] = (struct brw_texture*)texture; /* ptr, not struct */ + pipe_reference_texture(pipe, + (struct pipe_texture **) &brw->attribs.Texture[unit], + texture); brw->state.dirty.brw |= BRW_NEW_TEXTURE; } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index 043a2ff9a4..86ce3d0cc3 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -308,6 +308,7 @@ brw_texture_create(struct pipe_context *pipe, if (tex) { tex->base = *templat; + tex->base.refcount = 1; if (brw_miptree_layout(pipe, tex)) tex->buffer = pipe->winsys->buffer_create(pipe->winsys, 64, diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index b70d4fea85..a50cee7648 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -68,7 +68,7 @@ struct softpipe_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct softpipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index cf1b1eff75..2f40e09d5c 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -142,7 +142,7 @@ static void shade_begin(struct quad_stage *qs) /* set TGSI sampler state that varies */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { qss->samplers[i].state = softpipe->sampler[i]; - qss->samplers[i].texture = &softpipe->texture[i]->base; + qss->samplers[i].texture = softpipe->texture[i]; } /* find output slots for depth, color */ diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index 9246915e19..18669a1c6e 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -30,6 +30,7 @@ */ #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "draw/draw_context.h" @@ -82,7 +83,7 @@ softpipe_set_sampler_texture(struct pipe_context *pipe, draw_flush(softpipe->draw); assert(unit < PIPE_MAX_SAMPLERS); - softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ + pipe_texture_reference(pipe, &softpipe->texture[unit], texture); sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture); diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 295704c05f..6ba0f09e0a 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -89,6 +89,7 @@ softpipe_texture_create(struct pipe_context *pipe, return NULL; spt->base = *templat; + spt->base.refcount = 1; softpipe_texture_layout(spt); @@ -100,6 +101,8 @@ softpipe_texture_create(struct pipe_context *pipe, return NULL; } + assert(spt->base.refcount == 1); + return &spt->base; } @@ -136,7 +139,7 @@ softpipe_texture_update(struct pipe_context *pipe, struct softpipe_context *softpipe = softpipe_context(pipe); uint unit; for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) { - if (softpipe->texture[unit] == softpipe_texture(texture)) { + if (softpipe->texture[unit] == texture) { sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); } } diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index b86f416c9b..ad284170e4 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -76,7 +76,7 @@ st_texture_create(struct st_context *st, GLuint depth0, GLuint compress_byte) { - struct pipe_texture pt; + struct pipe_texture pt, *newtex; assert(target <= PIPE_TEXTURE_CUBE); @@ -95,9 +95,12 @@ st_texture_create(struct st_context *st, pt.depth[0] = depth0; pt.compressed = compress_byte ? 1 : 0; pt.cpp = pt.compressed ? compress_byte : st_sizeof_format(format); - pt.refcount = 1; - return st->pipe->texture_create(st->pipe, &pt); + newtex = st->pipe->texture_create(st->pipe, &pt); + + assert(!newtex || newtex->refcount == 1); + + return newtex; } -- cgit v1.2.3 From e523ef72044d7f8137a298d60597b8913bae9145 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 15:13:33 -0700 Subject: cell: use pipe_texture_reference() --- src/gallium/drivers/cell/ppu/cell_pipe_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 35e88f79b1..95bfc29fbe 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -242,7 +242,9 @@ cell_set_sampler_texture(struct pipe_context *pipe, draw_flush(cell->draw); - cell->texture[sampler] = cell_texture(texture); + pipe_texture_reference(pipe, + (struct pipe_texture **) &cell->texture[sampler], + texture); cell_update_texture_mapping(cell); -- cgit v1.2.3 From 228f6b978804268a482718e762ebfccbba784949 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 15:32:41 -0700 Subject: gallium: re-fix some msvc warnings --- src/gallium/auxiliary/draw/draw_aaline.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c index f1fee4f8ba..73a02a32e4 100644 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ b/src/gallium/auxiliary/draw/draw_aaline.c @@ -140,14 +140,14 @@ aa_transform_decl(struct tgsi_transform_context *ctx, aactx->colorOutput = decl->u.DeclarationRange.First; } else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { - if (decl->u.DeclarationRange.Last > aactx->maxSampler) + if ((int) decl->u.DeclarationRange.Last > aactx->maxSampler) aactx->maxSampler = decl->u.DeclarationRange.Last + 1; } else if (decl->Declaration.File == TGSI_FILE_INPUT) { - if (decl->u.DeclarationRange.Last > aactx->maxInput) + if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) aactx->maxInput = decl->u.DeclarationRange.Last; - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && - decl->Semantic.SemanticIndex > aactx->maxGeneric) { + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { aactx->maxGeneric = decl->Semantic.SemanticIndex; } } @@ -393,7 +393,7 @@ aaline_create_texture(struct aaline_stage *aaline) for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { - uint d; + ubyte d; if (size == 1) { d = 255; } @@ -494,12 +494,12 @@ aaline_line(struct draw_stage *stage, struct prim_header *header) float *pos, *tex; float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; - float a = atan2(dy, dx); - float c_a = cos(a), s_a = sin(a); + double a = atan2(dy, dx); + float c_a = (float) cos(a), s_a = (float) sin(a); uint i; /* XXX the ends of lines aren't quite perfect yet, but probably passable */ - dx = 0.5 * half_width; + dx = 0.5F * half_width; dy = half_width; /* allocate/dup new verts */ -- cgit v1.2.3 From d3b7d26b0bab6587cfad64735aefa28d8377c358 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 17:57:40 -0700 Subject: gallium: s/pipe_reference_texture/pipe_texture_reference/ --- src/gallium/drivers/i965simple/brw_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index f269b2882c..254e3f7245 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -327,7 +327,7 @@ static void brw_set_sampler_texture(struct pipe_context *pipe, { struct brw_context *brw = brw_context(pipe); - pipe_reference_texture(pipe, + pipe_texture_reference(pipe, (struct pipe_texture **) &brw->attribs.Texture[unit], texture); -- cgit v1.2.3 From 8be9bc08e1da31619f1b1c49aa6280d44f94c442 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 20 Feb 2008 18:00:03 -0700 Subject: gallium: include p_inlines.h --- src/gallium/drivers/i965simple/brw_state.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index 254e3f7245..2fc048bde0 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -32,6 +32,7 @@ #include "pipe/p_winsys.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "pipe/p_shader_tokens.h" #include "tgsi/util/tgsi_dump.h" -- cgit v1.2.3 From 7c74037852a484a8a50e8bc540b954a624de4d33 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 20 Feb 2008 14:32:25 -0800 Subject: Cell: Initial pass at unified data cache --- src/gallium/drivers/cell/common.h | 8 ++ src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 6 +- src/gallium/drivers/cell/ppu/cell_flush.c | 14 ++++ src/gallium/drivers/cell/spu/spu_dcache.c | 100 ++++++++++++++++++++++++ src/gallium/drivers/cell/spu/spu_dcache.h | 34 ++++++++ src/gallium/drivers/cell/spu/spu_exec.c | 49 ++++++------ src/gallium/drivers/cell/spu/spu_main.c | 8 ++ src/gallium/drivers/cell/spu/spu_vertex_fetch.c | 70 +---------------- 8 files changed, 194 insertions(+), 95 deletions(-) create mode 100644 src/gallium/drivers/cell/spu/spu_dcache.c create mode 100644 src/gallium/drivers/cell/spu/spu_dcache.h (limited to 'src') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index cf892206c6..f32ad5bfbe 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -93,6 +93,7 @@ #define CELL_CMD_STATE_BLEND 19 #define CELL_CMD_STATE_ATTRIB_FETCH 20 #define CELL_CMD_VS_EXECUTE 21 +#define CELL_CMD_FLUSH_BUFFER_RANGE 22 #define CELL_NUM_BUFFERS 4 @@ -144,6 +145,13 @@ struct cell_attribute_fetch_code { uint size; }; + +struct cell_buffer_range { + uint64_t base; + unsigned size; +}; + + struct cell_shader_info { uint64_t declarations; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index f12613649b..cbd387f014 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -49,9 +49,12 @@ cell_map_constant_buffers(struct cell_context *sp) struct pipe_winsys *ws = sp->pipe.winsys; uint i; for (i = 0; i < 2; i++) { - if (sp->constants[i].size) + if (sp->constants[i].size) { sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, PIPE_BUFFER_USAGE_CPU_READ); + cell_flush_buffer_range(sp, sp->mapped_constants[i], + sp->constants[i].buffer->size); + } } draw_set_mapped_constant_buffer(sp->draw, @@ -124,6 +127,7 @@ cell_draw_elements(struct pipe_context *pipe, void *buf = pipe->winsys->buffer_map(pipe->winsys, sp->vertex_buffer[i].buffer, PIPE_BUFFER_USAGE_CPU_READ); + cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size); draw_set_mapped_vertex_buffer(draw, i, buf); } } diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c index 20f27531fc..66a5627d84 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.c +++ b/src/gallium/drivers/cell/ppu/cell_flush.c @@ -82,3 +82,17 @@ cell_flush_int(struct pipe_context *pipe, unsigned flags) flushing = FALSE; } + + +void +cell_flush_buffer_range(struct cell_context *cell, void *ptr, + unsigned size) +{ + uint64_t batch[1 + (ROUNDUP8(sizeof(struct cell_buffer_range)) / 8)]; + struct cell_buffer_range *br = (struct cell_buffer_range *) & batch[1]; + + batch[0] = CELL_CMD_FLUSH_BUFFER_RANGE; + br->base = (uintptr_t) ptr; + br->size = size; + cell_batch_append(cell, batch, sizeof(batch)); +} diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c new file mode 100644 index 0000000000..9e30e17880 --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -0,0 +1,100 @@ +/* + * (C) Copyright IBM Corporation 2008 + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "spu_main.h" +#include "spu_dcache.h" + +#define CACHE_NAME data +#define CACHED_TYPE qword +#define CACHE_TYPE CACHE_TYPE_RO +#define CACHE_SET_TAGID(set) TAG_VERTEX_BUFFER +#define CACHE_LOG2NNWAY 2 +#define CACHE_LOG2NSETS 6 +#include + +/* Yes folks, this is ugly. + */ +#undef CACHE_NWAY +#undef CACHE_NSETS +#define CACHE_NAME data +#define CACHE_NWAY 4 +#define CACHE_NSETS (1U << 6) + + +/** + * Fetch between arbitrary number of bytes from an unaligned address + */ +void +spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) +{ + const int shift = ea & 0x0f; + const unsigned aligned_start_ea = ea & ~0x0f; + const unsigned aligned_end_ea = (ea + size) & ~0x0f; + const unsigned num_entries = ((aligned_end_ea - aligned_start_ea) / 16) + 1; + unsigned i; + + + if (shift == 0) { + /* Data is already aligned. Fetch directly into the destination buffer. + */ + for (i = 0; i < num_entries; i++) { + dst[i] = cache_rd(data, (ea & ~0x0f) + (i * 16)); + } + } else { + qword tmp[2] ALIGN16_ATTRIB; + + + tmp[0] = cache_rd(data, (ea & ~0x0f)); + for (i = 0; i < (num_entries & ~1); i++) { + const unsigned curr = i & 1; + const unsigned next = curr ^ 1; + + tmp[next] = cache_rd(data, (ea & ~0x0f) + (next * 16)); + + dst[i] = si_or((qword) spu_slqwbyte(tmp[curr], shift), + (qword) spu_rlmaskqwbyte(tmp[next], shift - 16)); + } + + if (i < num_entries) { + dst[i] = si_or((qword) spu_slqwbyte(tmp[(i & 1)], shift), + si_il(0)); + } + } +} + + +void +spu_dcache_mark_dirty(unsigned ea, unsigned size) +{ + unsigned i; + + (void) ea; + (void) size; + + /* Invalidate the whole cache for now. + */ + for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) { + CACHELINE_CLEARVALID(i); + } +} diff --git a/src/gallium/drivers/cell/spu/spu_dcache.h b/src/gallium/drivers/cell/spu/spu_dcache.h new file mode 100644 index 0000000000..7a06b8c25a --- /dev/null +++ b/src/gallium/drivers/cell/spu/spu_dcache.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright IBM Corporation 2008 + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SPU_DCACHE_H +#define SPU_DCACHE_H + +extern void +spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size); + +extern void +spu_dcache_mark_dirty(unsigned ea, unsigned size); + +#endif /* SPU_DCACHE_H */ diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 0eb5ea1a3f..94ac6a2885 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -72,6 +72,7 @@ #include "spu_exec.h" #include "spu_main.h" #include "spu_vertex_shader.h" +#include "spu_dcache.h" #define TILE_TOP_LEFT 0 #define TILE_TOP_RIGHT 1 @@ -352,19 +353,17 @@ fetch_src_file_channel( case TGSI_EXTSWIZZLE_W: switch( file ) { case TGSI_FILE_CONSTANT: { - unsigned char buffer[32] ALIGN16_ATTRIB; unsigned i; for (i = 0; i < 4; i++) { const float *ptr = mach->Consts[index->i[i]]; - const uint64_t addr = (uint64_t)(uintptr_t) ptr; - const unsigned size = ((addr & 0x0f) == 0) ? 16 : 32; + float tmp[4]; - mfc_get(buffer, addr & ~0x0f, size, TAG_VERTEX_BUFFER, 0, 0); - wait_on_mask(1 << TAG_VERTEX_BUFFER); + spu_dcache_fetch_unaligned((qword *) tmp, + (uintptr_t)(ptr + swizzle), + sizeof(float)); - (void) memcpy(& chan->f[i], &buffer[(addr & 0x0f) - + (sizeof(float) * swizzle)], sizeof(float)); + chan->f[i] = tmp[0]; } break; } @@ -1899,32 +1898,30 @@ spu_exec_machine_run( struct spu_exec_machine *mach ) /* execute declarations (interpolants) */ if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { for (i = 0; i < mach->NumDeclarations; i++) { - uint8_t buffer[sizeof(struct tgsi_full_declaration) + 32] ALIGN16_ATTRIB; - struct tgsi_full_declaration decl; - unsigned long decl_addr = (unsigned long) (mach->Declarations+i); - unsigned size = ((sizeof(decl) + (decl_addr & 0x0f) + 0x0f) & ~0x0f); + union { + struct tgsi_full_declaration decl; + qword buffer[2 * ((sizeof(struct tgsi_full_declaration) + 31) + / 32)]; + } d ALIGN16_ATTRIB; + unsigned ea = (unsigned) (mach->Declarations + pc); - mfc_get(buffer, decl_addr & ~0x0f, size, TAG_INSTRUCTION_FETCH, 0, 0); - wait_on_mask(1 << TAG_INSTRUCTION_FETCH); + spu_dcache_fetch_unaligned(d.buffer, ea, sizeof(d.decl)); - memcpy(& decl, buffer + (decl_addr & 0x0f), sizeof(decl)); - exec_declaration( mach, &decl ); + exec_declaration( mach, &d.decl ); } } /* execute instructions, until pc is set to -1 */ while (pc != -1) { - uint8_t buffer[sizeof(struct tgsi_full_instruction) + 32] ALIGN16_ATTRIB; - struct tgsi_full_instruction inst; - unsigned long inst_addr = (unsigned long) (mach->Instructions + pc); - unsigned size = ((sizeof(inst) + (inst_addr & 0x0f) + 0x0f) & ~0x0f); - - assert(pc < mach->NumInstructions); - mfc_get(buffer, inst_addr & ~0x0f, size, TAG_INSTRUCTION_FETCH, 0, 0); - wait_on_mask(1 << TAG_INSTRUCTION_FETCH); - - memcpy(& inst, buffer + (inst_addr & 0x0f), sizeof(inst)); - exec_instruction( mach, & inst, &pc ); + union { + struct tgsi_full_instruction inst; + qword buffer[2 * ((sizeof(struct tgsi_full_instruction) + 31) + / 32)]; + } i ALIGN16_ATTRIB; + unsigned ea = (unsigned) (mach->Instructions + pc); + + spu_dcache_fetch_unaligned(i.buffer, ea, sizeof(i.inst)); + exec_instruction( mach, & i.inst, &pc ); } #if 0 diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index dbc3705c24..1136dba62d 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -462,6 +462,14 @@ cmd_batch(uint opcode) pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8); break; } + case CELL_CMD_FLUSH_BUFFER_RANGE: { + struct cell_buffer_range *br = (struct cell_buffer_range *) + &buffer[pos+1]; + + spu_dcache_mark_dirty((unsigned) br->base, br->size); + pos += (1 + ROUNDUP8(sizeof(struct cell_buffer_range)) / 8); + break; + } default: printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]); ASSERT(0); diff --git a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c index e5d9910ff3..f7e4e653e3 100644 --- a/src/gallium/drivers/cell/spu/spu_vertex_fetch.c +++ b/src/gallium/drivers/cell/spu/spu_vertex_fetch.c @@ -40,25 +40,7 @@ #include "spu_exec.h" #include "spu_vertex_shader.h" #include "spu_main.h" - -#define CACHE_NAME attribute -#define CACHED_TYPE qword -#define CACHE_TYPE CACHE_TYPE_RO -#define CACHE_SET_TAGID(set) TAG_VERTEX_BUFFER -#define CACHE_LOG2NNWAY 2 -#define CACHE_LOG2NSETS 6 -#include - -/* Yes folks, this is ugly. - */ -#undef CACHE_NWAY -#undef CACHE_NSETS -#define CACHE_NAME attribute -#define CACHE_NWAY 4 -#define CACHE_NSETS (1U << 6) - - -#define DRAW_DBG 0 +#include "spu_dcache.h" typedef void (*spu_fetch_func)(qword *out, const qword *in, const qword *shuffle_data); @@ -102,44 +84,6 @@ static const qword fetch_shuffle_data[5] ALIGN16_ATTRIB = { }; -/** - * Fetch between 1 and 32 bytes from an unaligned address - */ -static INLINE void -fetch_unaligned(qword *dst, unsigned ea, unsigned size) -{ - qword tmp[4] ALIGN16_ATTRIB; - const int shift = ea & 0x0f; - const unsigned aligned_start_ea = ea & ~0x0f; - const unsigned aligned_end_ea = (ea + size) & ~0x0f; - const unsigned num_entries = ((aligned_end_ea - aligned_start_ea) / 16) + 1; - unsigned i; - - - if (shift == 0) { - /* Data is already aligned. Fetch directly into the destination buffer. - */ - for (i = 0; i < num_entries; i++) { - dst[i] = cache_rd(attribute, (ea & ~0x0f) + (i * 16)); - } - } else { - /* Fetch data from the cache to the local buffer. - */ - for (i = 0; i < num_entries; i++) { - tmp[i] = cache_rd(attribute, (ea & ~0x0f) + (i * 16)); - } - - - /* Fix the alignment of the data and write to the destination buffer. - */ - for (i = 0; i < ((size + 15) / 16); i++) { - dst[i] = si_or((qword) spu_slqwbyte(tmp[i], shift), - (qword) spu_rlmaskqwbyte(tmp[i + 1], shift - 16)); - } - } -} - - /** * Fetch vertex attributes for 'count' vertices. */ @@ -182,7 +126,7 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, printf("SPU: fetching = 0x%llx\n", addr); #endif - fetch_unaligned(& in[idx], addr, bytes_per_entry); + spu_dcache_fetch_unaligned(& in[idx], addr, bytes_per_entry); idx += quads_per_entry; } @@ -200,15 +144,5 @@ static void generic_vertex_fetch(struct spu_vs_context *draw, void spu_update_vertex_fetch( struct spu_vs_context *draw ) { - unsigned i; - - - /* Invalidate the vertex cache. - */ - for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) { - CACHELINE_CLEARVALID(i); - } - - draw->vertex_fetch.fetch_func = generic_vertex_fetch; } -- cgit v1.2.3 From 2d1f086c12b6d64f5c3fb80474f26775aeb71370 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 20 Feb 2008 14:45:08 -0800 Subject: Cell: Fix off-by-one error in spu_dcache_fetch_unaligned An off-by-one error caused an extra qword to be fetched under certain alignment / size combinations. --- src/gallium/drivers/cell/spu/spu_dcache.c | 5 +++-- src/gallium/drivers/cell/spu/spu_exec.c | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c index 9e30e17880..68aa5c4ae8 100644 --- a/src/gallium/drivers/cell/spu/spu_dcache.c +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -22,6 +22,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "cell/common.h" #include "spu_main.h" #include "spu_dcache.h" @@ -50,8 +51,8 @@ spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) { const int shift = ea & 0x0f; const unsigned aligned_start_ea = ea & ~0x0f; - const unsigned aligned_end_ea = (ea + size) & ~0x0f; - const unsigned num_entries = ((aligned_end_ea - aligned_start_ea) / 16) + 1; + const unsigned aligned_end_ea = ROUNDUP16(ea + size); + const unsigned num_entries = (aligned_end_ea - aligned_start_ea) / 16; unsigned i; diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c index 94ac6a2885..cf81bee8fd 100644 --- a/src/gallium/drivers/cell/spu/spu_exec.c +++ b/src/gallium/drivers/cell/spu/spu_exec.c @@ -73,6 +73,7 @@ #include "spu_main.h" #include "spu_vertex_shader.h" #include "spu_dcache.h" +#include "cell/common.h" #define TILE_TOP_LEFT 0 #define TILE_TOP_RIGHT 1 @@ -1900,8 +1901,7 @@ spu_exec_machine_run( struct spu_exec_machine *mach ) for (i = 0; i < mach->NumDeclarations; i++) { union { struct tgsi_full_declaration decl; - qword buffer[2 * ((sizeof(struct tgsi_full_declaration) + 31) - / 32)]; + qword buffer[ROUNDUP16(sizeof(struct tgsi_full_declaration)) / 16]; } d ALIGN16_ATTRIB; unsigned ea = (unsigned) (mach->Declarations + pc); @@ -1915,8 +1915,7 @@ spu_exec_machine_run( struct spu_exec_machine *mach ) while (pc != -1) { union { struct tgsi_full_instruction inst; - qword buffer[2 * ((sizeof(struct tgsi_full_instruction) + 31) - / 32)]; + qword buffer[ROUNDUP16(sizeof(struct tgsi_full_instruction)) / 16]; } i ALIGN16_ATTRIB; unsigned ea = (unsigned) (mach->Instructions + pc); -- cgit v1.2.3 From e78fc9f2f4d89b0cae0d56d84dd16cb76a6757dc Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 21 Feb 2008 09:03:29 -0800 Subject: Cell: Initial scalar implementation of spu_dcache_mark_dirty --- src/gallium/drivers/cell/spu/spu_dcache.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/spu/spu_dcache.c b/src/gallium/drivers/cell/spu/spu_dcache.c index 68aa5c4ae8..698a5790bb 100644 --- a/src/gallium/drivers/cell/spu/spu_dcache.c +++ b/src/gallium/drivers/cell/spu/spu_dcache.c @@ -26,6 +26,10 @@ #include "spu_main.h" #include "spu_dcache.h" +#define CACHELINE_LOG2SIZE 7 +#define LINE_SIZE (1U << 7) +#define ALIGN_MASK (~(LINE_SIZE - 1)) + #define CACHE_NAME data #define CACHED_TYPE qword #define CACHE_TYPE CACHE_TYPE_RO @@ -60,7 +64,7 @@ spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) /* Data is already aligned. Fetch directly into the destination buffer. */ for (i = 0; i < num_entries; i++) { - dst[i] = cache_rd(data, (ea & ~0x0f) + (i * 16)); + dst[i] = cache_rd(data, ea + (i * 16)); } } else { qword tmp[2] ALIGN16_ATTRIB; @@ -85,17 +89,23 @@ spu_dcache_fetch_unaligned(qword *dst, unsigned ea, unsigned size) } +/** + * Notify the cache that a range of main memory may have been modified + */ void spu_dcache_mark_dirty(unsigned ea, unsigned size) { unsigned i; + const unsigned aligned_start = (ea & ALIGN_MASK); + const unsigned aligned_end = (ea + size + (LINE_SIZE - 1)) + & ALIGN_MASK; - (void) ea; - (void) size; - /* Invalidate the whole cache for now. - */ for (i = 0; i < (CACHE_NWAY * CACHE_NSETS); i++) { - CACHELINE_CLEARVALID(i); + const unsigned entry = __cache_dir[i]; + const unsigned addr = entry & ~0x0f; + + __cache_dir[i] = ((addr >= aligned_start) && (addr < aligned_end)) + ? (entry & ~CACHELINE_VALID) : entry; } } -- cgit v1.2.3 From 6dd47c264a8642a4e3dbe0b4fc194174743c64fc Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 21 Feb 2008 10:24:29 -0800 Subject: Cell: Add spu_dcache.c to Makefile. This was erroneously missing in previous commits. --- src/gallium/drivers/cell/spu/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile index 30ef2450ec..c071de1900 100644 --- a/src/gallium/drivers/cell/spu/Makefile +++ b/src/gallium/drivers/cell/spu/Makefile @@ -18,6 +18,7 @@ PROG_SPU_EMBED_O = $(PROG)_spu-embed.o SOURCES = \ spu_main.c \ spu_blend.c \ + spu_dcache.c \ spu_render.c \ spu_texture.c \ spu_tile.c \ -- cgit v1.2.3 From de5c64e0af0b1a1ce3ee12f361341880dc260868 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 21 Feb 2008 10:32:02 -0800 Subject: Cell: Remove erroneous ALIGN16_ATTRIB attributes If a structure is marked as being aligned the SPE compiler performs extra optimizations (sadly, only -O2 is used) when reading the structure. Since most of the structures sent in batch buffers are only 8-byte aligned, this resulted in mysterous bugs with -O2. --- src/gallium/drivers/cell/common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index f32ad5bfbe..9a4004535e 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -137,7 +137,7 @@ struct cell_array_info uint pitch; /**< Byte pitch from one entry to the next. */ uint size; uint function_offset; -} ALIGN16_ATTRIB; +}; struct cell_attribute_fetch_code { @@ -162,7 +162,7 @@ struct cell_shader_info unsigned num_declarations; unsigned num_instructions; unsigned num_immediates; -} ALIGN16_ATTRIB; +}; #define SPU_VERTS_PER_BATCH 64 @@ -175,7 +175,7 @@ struct cell_command_vs float plane[12][4]; unsigned nr_planes; unsigned nr_attrs; -} ALIGN16_ATTRIB; +}; struct cell_command_render -- cgit v1.2.3 From 1eaf7b775ba0dacff8a3debd7c0f260970e5a61d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 15 Feb 2008 18:54:00 +0000 Subject: tgsi: print debug messages on failure to codegenerate --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 29a7f842ed..779b901f2b 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2356,11 +2356,17 @@ tgsi_emit_sse2_fs( ok = emit_instruction( func, &parse.FullToken.FullInstruction ); + + if (!ok) { + debug_printf("failed to translate tgsi opcode %d\n", + parse.FullToken.FullInstruction.Instruction.Opcode ); + } break; case TGSI_TOKEN_TYPE_IMMEDIATE: /* XXX implement this */ ok = 0; + debug_printf("failed to emit immediate value\n"); break; default: -- cgit v1.2.3 From 30479ef11004c9498c4ef09048efc56227f104cc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 15 Feb 2008 18:56:41 +0000 Subject: draw: vertex cache rework Take a baby step to straightening out vertex paths. --- src/gallium/auxiliary/draw/draw_context.c | 8 ++-- src/gallium/auxiliary/draw/draw_prim.c | 2 + src/gallium/auxiliary/draw/draw_private.h | 13 ++++-- src/gallium/auxiliary/draw/draw_vertex_cache.c | 60 ++++++++++++++----------- src/gallium/auxiliary/draw/draw_vertex_shader.c | 7 +-- 5 files changed, 53 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index a7f3b4aecb..b90a9f474d 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -72,10 +72,10 @@ struct draw_context *draw_create( void ) { uint i; const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f; - char *tmp = align_malloc(Elements(draw->vcache.vertex) * size, 16); + char *tmp = align_malloc(Elements(draw->vs.queue) * size, 16); - for (i = 0; i < Elements(draw->vcache.vertex); i++) - draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * size); + for (i = 0; i < Elements(draw->vs.queue); i++) + draw->vs.queue[i].vertex = (struct vertex_header *)(tmp + i * size); } draw->shader_queue_flush = draw_vertex_shader_queue_flush; @@ -108,7 +108,7 @@ void draw_destroy( struct draw_context *draw ) if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); tgsi_exec_machine_free_data(&draw->machine); - align_free( draw->vcache.vertex[0] ); /* Frees all the vertices. */ + align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */ FREE( draw ); } diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index dd9a848863..7d6cd43410 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -114,6 +114,7 @@ static void draw_prim_queue_flush( struct draw_context *draw ) } draw->pq.queue_nr = 0; + draw->vs.post_nr = 0; draw_vertex_cache_unreference( draw ); } @@ -226,6 +227,7 @@ static void do_triangle( struct draw_context *draw, { struct prim_header *prim = get_queued_prim( draw, 3 ); +// _mesa_printf("tri %d %d %d\n", i0, i1, i2); prim->reset_line_stipple = 1; prim->edgeflags = ~0; prim->pad = 0; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 6c7e860861..492c152ff9 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -120,7 +120,7 @@ struct draw_stage }; -#define PRIM_QUEUE_LENGTH 16 +#define PRIM_QUEUE_LENGTH 32 #define VCACHE_SIZE 32 #define VCACHE_OVERFLOW 4 #define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ @@ -244,8 +244,12 @@ struct draw_context */ struct { unsigned referenced; /**< bitfield */ - unsigned idx[VCACHE_SIZE + VCACHE_OVERFLOW]; - struct vertex_header *vertex[VCACHE_SIZE + VCACHE_OVERFLOW]; + + struct { + unsigned in; /* client array element */ + unsigned out; /* index in vs queue/array */ + } idx[VCACHE_SIZE + VCACHE_OVERFLOW]; + unsigned overflow; /** To find space in the vertex cache: */ @@ -258,9 +262,10 @@ struct draw_context struct { struct { unsigned elt; /**< index into the user's vertex arrays */ - struct vertex_header *dest; /**< points into vcache.vertex[] array */ + struct vertex_header *vertex; } queue[VS_QUEUE_LENGTH]; unsigned queue_nr; + unsigned post_nr; } vs; /** diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c index 44427999cc..53f8bbec44 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c @@ -41,7 +41,7 @@ void draw_vertex_cache_invalidate( struct draw_context *draw ) assert(draw->vs.queue_nr == 0); assert(draw->vcache.referenced == 0); - memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); +// memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); } @@ -62,43 +62,51 @@ static struct vertex_header *get_vertex( struct draw_context *draw, assert(slot < 32); /* so we don't exceed the bitfield size below */ - /* Cache miss? - */ - if (draw->vcache.idx[slot] != i) { - - /* If slot is in use, use the overflow area: + if (draw->vcache.referenced & (1<vcache.referenced & (1 << slot)) { - slot = VCACHE_SIZE + draw->vcache.overflow++; + if (draw->vcache.idx[slot].in == i) { +// _mesa_printf("HIT %d %d\n", slot, i); + assert(draw->vcache.idx[slot].out < draw->vs.queue_nr); + return draw->vs.queue[draw->vcache.idx[slot].out].vertex; } + /* Otherwise a collision + */ + slot = VCACHE_SIZE + draw->vcache.overflow++; +// _mesa_printf("XXX %d --> %d\n", i, slot); + } + + /* Deal with the cache miss: + */ + { + unsigned out; + assert(slot < Elements(draw->vcache.idx)); - draw->vcache.idx[slot] = i; +// _mesa_printf("NEW %d %d\n", slot, i); + draw->vcache.idx[slot].in = i; + draw->vcache.idx[slot].out = out = draw->vs.queue_nr++; + draw->vcache.referenced |= (1 << slot); + /* Add to vertex shader queue: */ assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); - draw->vs.queue[draw->vs.queue_nr].dest = draw->vcache.vertex[slot]; - draw->vs.queue[draw->vs.queue_nr].elt = i; - draw->vs.queue_nr++; + + draw->vs.queue[out].elt = i; + draw->vs.queue[out].vertex->clipmask = 0; + draw->vs.queue[out].vertex->edgeflag = 1; /*XXX use user's edge flag! */ + draw->vs.queue[out].vertex->pad = 0; + draw->vs.queue[out].vertex->vertex_id = UNDEFINED_VERTEX_ID; /* Need to set the vertex's edge flag here. If we're being called * by do_ef_triangle(), that function needs edge flag info! */ - draw->vcache.vertex[slot]->clipmask = 0; - draw->vcache.vertex[slot]->edgeflag = 1; /*XXX use user's edge flag! */ - draw->vcache.vertex[slot]->pad = 0; - draw->vcache.vertex[slot]->vertex_id = UNDEFINED_VERTEX_ID; - } - - /* primitive flushing may have cleared the bitfield but did not - * clear the idx[] array values. Set the bit now. This fixes a - * bug found when drawing long triangle fans. - */ - draw->vcache.referenced |= (1 << slot); - return draw->vcache.vertex[slot]; + return draw->vs.queue[draw->vcache.idx[slot].out].vertex; + } } @@ -130,8 +138,8 @@ void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) { unsigned i; - for (i = 0; i < Elements(draw->vcache.vertex); i++) - draw->vcache.vertex[i]->vertex_id = UNDEFINED_VERTEX_ID; + for (i = 0; i < draw->vs.post_nr; i++) + draw->vs.queue[i].vertex->vertex_id = UNDEFINED_VERTEX_ID; } diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index f68f6e3244..5d2f5c9c43 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -55,7 +55,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) */ shader->prepare( shader, draw ); -// fprintf(stderr, " q(%d) ", draw->vs.queue_nr ); +// fprintf(stderr, "%s %d\n", __FUNCTION__, draw->vs.queue_nr ); /* run vertex shader on vertex cache entries, four per invokation */ for (i = 0; i < draw->vs.queue_nr; i += 4) { @@ -65,12 +65,12 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) for (j = 0; j < n; j++) { elts[j] = draw->vs.queue[i + j].elt; - dests[j] = draw->vs.queue[i + j].dest; + dests[j] = draw->vs.queue[i + j].vertex; } for ( ; j < 4; j++) { elts[j] = elts[0]; - dests[j] = dests[0]; + dests[j] = draw->vs.queue[i + j].vertex; } assert(n > 0); @@ -79,6 +79,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) shader->run(shader, draw, elts, n, dests); } + draw->vs.post_nr = draw->vs.queue_nr; draw->vs.queue_nr = 0; } -- cgit v1.2.3 From 4339744c1676f925d42251bd32795bba9928cd5f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 21 Feb 2008 10:07:58 +0000 Subject: [PATCH] gallium: include p_compiler.h for boolean defn --- src/gallium/include/pipe/p_shader_tokens.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index 3ce35310f6..10c47e0ef0 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -5,6 +5,8 @@ extern "C" { #endif // defined __cplusplus +#include "p_compiler.h" + struct tgsi_version { unsigned MajorVersion : 8; -- cgit v1.2.3 From 20fbcbf5801c28865c0bfab3cda45302c8474a66 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 21 Feb 2008 19:07:31 +0000 Subject: [PATCH] softpipe: unbreak sp_setup_pos_vector on non-x86 systems --- src/gallium/drivers/softpipe/sp_fs_exec.c | 35 +++++++++++++++++++++++++++++++ src/gallium/drivers/softpipe/sp_fs_sse.c | 35 ------------------------------- 2 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 9ad30a7681..8cb0534342 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -44,6 +44,41 @@ struct sp_exec_fragment_shader { +/** + * Compute quad X,Y,Z,W for the four fragments in a quad. + * + * This should really be part of the compiled shader. + */ +void +sp_setup_pos_vector(const struct tgsi_interp_coef *coef, + float x, float y, + struct tgsi_exec_vector *quadpos) +{ + uint chan; + /* do X */ + quadpos->xyzw[0].f[0] = x; + quadpos->xyzw[0].f[1] = x + 1; + quadpos->xyzw[0].f[2] = x; + quadpos->xyzw[0].f[3] = x + 1; + + /* do Y */ + quadpos->xyzw[1].f[0] = y; + quadpos->xyzw[1].f[1] = y; + quadpos->xyzw[1].f[2] = y + 1; + quadpos->xyzw[1].f[3] = y + 1; + + /* do Z and W for all fragments in the quad */ + for (chan = 2; chan < 4; chan++) { + const float dadx = coef->dadx[chan]; + const float dady = coef->dady[chan]; + const float a0 = coef->a0[chan] + dadx * x + dady * y; + quadpos->xyzw[chan].f[0] = a0; + quadpos->xyzw[chan].f[1] = a0 + dadx; + quadpos->xyzw[chan].f[2] = a0 + dady; + quadpos->xyzw[chan].f[3] = a0 + dadx + dady; + } +} + static void exec_prepare( struct sp_fragment_shader *base, diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 53050b7823..8095d662ee 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -63,41 +63,6 @@ struct sp_sse_fragment_shader { }; -/** - * Compute quad X,Y,Z,W for the four fragments in a quad. - * - * This should really be part of the compiled shader. - */ -void -sp_setup_pos_vector(const struct tgsi_interp_coef *coef, - float x, float y, - struct tgsi_exec_vector *quadpos) -{ - uint chan; - /* do X */ - quadpos->xyzw[0].f[0] = x; - quadpos->xyzw[0].f[1] = x + 1; - quadpos->xyzw[0].f[2] = x; - quadpos->xyzw[0].f[3] = x + 1; - - /* do Y */ - quadpos->xyzw[1].f[0] = y; - quadpos->xyzw[1].f[1] = y; - quadpos->xyzw[1].f[2] = y + 1; - quadpos->xyzw[1].f[3] = y + 1; - - /* do Z and W for all fragments in the quad */ - for (chan = 2; chan < 4; chan++) { - const float dadx = coef->dadx[chan]; - const float dady = coef->dady[chan]; - const float a0 = coef->a0[chan] + dadx * x + dady * y; - quadpos->xyzw[chan].f[0] = a0; - quadpos->xyzw[chan].f[1] = a0 + dadx; - quadpos->xyzw[chan].f[2] = a0 + dady; - quadpos->xyzw[chan].f[3] = a0 + dadx + dady; - } -} - static void fs_sse_prepare( struct sp_fragment_shader *base, -- cgit v1.2.3 From d4d2e36a429fd015316c484fc40be7e6d2c69946 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Feb 2008 08:37:49 -0700 Subject: gallium: comments, white-space clean-up --- src/gallium/include/pipe/p_state.h | 53 +++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 1082343e2f..47fa78c31d 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -66,7 +66,8 @@ struct pipe_winsys; * The driver will certainly subclass this to include actual memory * management information. */ -struct pipe_buffer { +struct pipe_buffer +{ unsigned alignment; unsigned usage; unsigned size; @@ -76,8 +77,6 @@ struct pipe_buffer { }; - - /** * Primitive (point/line/tri) rasterization info */ @@ -113,18 +112,21 @@ struct pipe_rasterizer_state }; -struct pipe_poly_stipple { +struct pipe_poly_stipple +{ unsigned stipple[32]; }; -struct pipe_viewport_state { +struct pipe_viewport_state +{ float scale[4]; float translate[4]; }; -struct pipe_scissor_state { +struct pipe_scissor_state +{ unsigned minx:16; unsigned miny:16; unsigned maxx:16; @@ -132,7 +134,8 @@ struct pipe_scissor_state { }; -struct pipe_clip_state { +struct pipe_clip_state +{ float ucp[PIPE_MAX_CLIP_PLANES][4]; unsigned nr; }; @@ -141,13 +144,15 @@ struct pipe_clip_state { /** * Constants for vertex/fragment shaders */ -struct pipe_constant_buffer { +struct pipe_constant_buffer +{ struct pipe_buffer *buffer; unsigned size; /** in bytes */ }; -struct pipe_shader_state { +struct pipe_shader_state +{ const struct tgsi_token *tokens; ubyte num_inputs; ubyte num_outputs; @@ -185,7 +190,8 @@ struct pipe_depth_stencil_alpha_state }; -struct pipe_blend_state { +struct pipe_blend_state +{ unsigned blend_enable:1; unsigned rgb_func:3; /**< PIPE_BLEND_x */ @@ -204,7 +210,8 @@ struct pipe_blend_state { }; -struct pipe_blend_color { +struct pipe_blend_color +{ float color[4]; }; @@ -224,19 +231,19 @@ struct pipe_framebuffer_state */ struct pipe_sampler_state { - unsigned wrap_s:3; /**< PIPE_TEX_WRAP_x */ - unsigned wrap_t:3; /**< PIPE_TEX_WRAP_x */ - unsigned wrap_r:3; /**< PIPE_TEX_WRAP_x */ + unsigned wrap_s:3; /**< PIPE_TEX_WRAP_x */ + unsigned wrap_t:3; /**< PIPE_TEX_WRAP_x */ + unsigned wrap_r:3; /**< PIPE_TEX_WRAP_x */ unsigned min_img_filter:2; /**< PIPE_TEX_FILTER_x */ unsigned min_mip_filter:2; /**< PIPE_TEX_MIPFILTER_x */ unsigned mag_img_filter:2; /**< PIPE_TEX_FILTER_x */ - unsigned compare:1; /**< shadow/depth compare enabled? */ - unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ - unsigned compare_func:3; /**< PIPE_FUNC_x */ - unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ - float shadow_ambient; /**< shadow test fail color/intensity */ - float lod_bias; /**< LOD/lambda bias */ - float min_lod, max_lod; /**< LOD clamp range, after bias */ + unsigned compare:1; /**< shadow/depth compare enabled? */ + unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ + unsigned compare_func:3; /**< PIPE_FUNC_x */ + unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ + float shadow_ambient; /**< shadow test fail color/intensity */ + float lod_bias; /**< LOD/lambda bias */ + float min_lod, max_lod; /**< LOD clamp range, after bias */ float border_color[4]; float max_anisotropy; }; @@ -248,10 +255,10 @@ struct pipe_sampler_state */ struct pipe_surface { - struct pipe_buffer *buffer; /**< driver private buffer handle */ + struct pipe_buffer *buffer; /**< surface's buffer/memory */ enum pipe_format format; /**< PIPE_FORMAT_x */ unsigned status; /**< PIPE_SURFACE_STATUS_x */ - unsigned clear_value; /**< may be temporary */ + unsigned clear_value; /**< XXX may be temporary */ unsigned cpp; /**< bytes per pixel */ unsigned width; unsigned height; -- cgit v1.2.3 From a93d8bfaf2aba1b2fe3ecfbb5bc4b7ff113c305e Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Feb 2008 12:32:38 -0700 Subject: gallium: fill in some blend/rasterizer template fields to make sure they're all valid, even if not relevant --- src/mesa/state_tracker/st_gen_mipmap.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index a0b4b973aa..c9765b2003 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -111,14 +111,22 @@ st_init_generate_mipmap(struct st_context *st) struct pipe_rasterizer_state rasterizer; struct pipe_depth_stencil_alpha_state depthstencil; + /* we don't use blending, but need to set valid values */ memset(&blend, 0, sizeof(blend)); + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; blend.colormask = PIPE_MASK_RGBA; st->gen_mipmap.blend_cso = pipe->create_blend_state(pipe, &blend); memset(&depthstencil, 0, sizeof(depthstencil)); st->gen_mipmap.depthstencil_cso = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil); + /* Note: we're assuming zero is valid for all non-specified fields */ memset(&rasterizer, 0, sizeof(rasterizer)); + rasterizer.front_winding = PIPE_WINDING_CW; + rasterizer.cull_mode = PIPE_WINDING_NONE; st->gen_mipmap.rasterizer_cso = pipe->create_rasterizer_state(pipe, &rasterizer); st->gen_mipmap.stfp = make_tex_fragment_program(st->ctx); -- cgit v1.2.3 From eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Feb 2008 16:18:05 -0700 Subject: gallium: new AA point drawing stage AA points are drawn by converting the point to a quad, then modifying the user's fragment shader to compute a coverage value. The final fragment color's alpha is modulated by the coverage value. Fragments outside the point's radius are killed. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_aapoint.c | 875 +++++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_context.c | 2 + src/gallium/auxiliary/draw/draw_context.h | 3 + src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_validate.c | 5 + src/gallium/drivers/softpipe/sp_context.c | 6 +- 7 files changed, 892 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/draw/draw_aapoint.c (limited to 'src') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 1ee9eca0ca..b7e71ed3ec 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -5,6 +5,7 @@ LIBNAME = draw C_SOURCES = \ draw_aaline.c \ + draw_aapoint.c \ draw_clip.c \ draw_vs_exec.c \ draw_vs_sse.c \ diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c new file mode 100644 index 0000000000..43119cc70b --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -0,0 +1,875 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * AA point stage: AA points are converted to quads and rendered with a + * special fragment shader. Another approach would be to use a texture + * map image of a point, but experiments indicate the quality isn't nearly + * as good as this approach. + * + * Note: this looks a lot like draw_aaline.c but there's actually little + * if any code that can be shared. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + +/* + * Enabling NORMALIZE might give _slightly_ better results. + * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or + * d=x*x+y*y. Since we're working with a unit circle, the later seems + * close enough and saves some costly instructions. + */ +#define NORMALIZE 0 + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct aapoint_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; /**< the regular shader */ + void *aapoint_fs; /**< the aa point-augmented shader */ +}; + + +/** + * Subclass of draw_stage + */ +struct aapoint_stage +{ + struct draw_stage stage; + + int psize_slot; + float radius; + + /** this is the vertex attrib slot for the new texcoords */ + uint tex_slot; + + /* + * Currently bound state + */ + struct aapoint_fragment_shader *fs; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct aa_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int colorOutput; /**< which output is the primary color */ + int maxInput, maxGeneric; /**< max input index found */ + int tmp0, colorTemp; /**< temp registers */ + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for two free temp regs and available input reg for new texcoords. + */ +static void +aa_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && + decl->Semantic.SemanticIndex == 0) { + aactx->colorOutput = decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->u.DeclarationRange.Last; + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { + aactx->maxGeneric = decl->Semantic.SemanticIndex; + } + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +aa_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + struct tgsi_full_instruction newInst; + + if (aactx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + const int texInput = aactx->maxInput + 1; + int tmp0; + uint i; + + /* find two free temp regs */ + for (i = 0; i < 32; i++) { + if ((aactx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (aactx->tmp0 < 0) + aactx->tmp0 = i; + else if (aactx->colorTemp < 0) + aactx->colorTemp = i; + else + break; + } + } + + assert(aactx->colorTemp != aactx->tmp0); + + tmp0 = aactx->tmp0; + + /* declare new generic input/texcoord */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; + decl.Declaration.Interpolate = 1; + /* XXX this could be linear... */ + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = texInput; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = tmp0; + ctx->emit_declaration(ctx, &decl); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->colorTemp; + ctx->emit_declaration(ctx, &decl); + + aactx->firstInstruction = FALSE; + + + /* + * Emit code to compute fragment coverage, kill if outside point radius + * + * Temp reg0 usage: + * t0.x = distance of fragment from center point + * t0.y = boolean, is t0.x > 1 ? + * t0.z = temporary for computing 1/(1-k) value + * t0.w = final coverage value + */ + + /* MUL t0.xy, tex, tex; # compute x^2, y^2 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + ctx->emit_instruction(ctx, &newInst); + + /* ADD t0.x, t0.x, t0.y; # x^2 + y^2 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_ADD; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + ctx->emit_instruction(ctx, &newInst); + +#if NORMALIZE /* OPTIONAL normalization of length */ + /* RSQ t0.x, t0.x; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RSQ; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.x, t0.x; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + ctx->emit_instruction(ctx, &newInst); +#endif + + /* SGT t0.y, t0.xxxx, t0.wwww; # bool b = d > 1 (NOTE t0.w == 1) */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SGT; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + ctx->emit_instruction(ctx, &newInst); + + /* KILP -t0.yyyy; # if b, KILL */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + + /* SGT t0.y, t0.x, tex.z; # bool b = distance > k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SGT; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* IF t0.y # if b then */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_IF; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + ctx->emit_instruction(ctx, &newInst); + + { + /* compute coverage factor = (1-d)/(1-k) */ + + /* SUB t0.z, tex.w, tex.z; # m = 1 - k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.z, t0.z; # t0.z = 1 / m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* SUB t0.x, 1, t0.x; # d = 1 - d */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + ctx->emit_instruction(ctx, &newInst); + + /* MUL t0.w, t0.x, t0.z; # coverage = d * m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + } + + /* ELSE */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_ELSE; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 0; + ctx->emit_instruction(ctx, &newInst); + + { + /* MOV t0.w, tex.w; # coverage = 1.0 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + ctx->emit_instruction(ctx, &newInst); + } + + /* ENDIF */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_ENDIF; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 0; + ctx->emit_instruction(ctx, &newInst); + } + + if (inst->Instruction.Opcode == TGSI_OPCODE_END) { + /* add alpha modulation code at tail of program */ + + /* MOV result.color.xyz, colorTemp; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + ctx->emit_instruction(ctx, &newInst); + + /* MUL result.color.w, colorTemp, tmp0.w; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0; + ctx->emit_instruction(ctx, &newInst); + } + else { + /* Not an END instruction. + * Look for writes to result.color and replace with colorTemp reg. + */ + uint i; + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + if (dst->DstRegister.File == TGSI_FILE_OUTPUT && + dst->DstRegister.Index == aactx->colorOutput) { + dst->DstRegister.File = TGSI_FILE_TEMPORARY; + dst->DstRegister.Index = aactx->colorTemp; + } + } + } + + ctx->emit_instruction(ctx, inst); +} + + +/** + * Generate the frag shader we'll use for drawing AA lines. + * This will be the user's shader plus some texture/modulate instructions. + */ +static void +generate_aapoint_fs(struct aapoint_stage *aapoint) +{ + const struct pipe_shader_state *orig_fs = &aapoint->fs->state; + struct draw_context *draw = aapoint->stage.draw; + struct pipe_shader_state aapoint_fs; + struct aa_transform_context transform; + +#define MAX 1000 + + aapoint_fs = *orig_fs; /* copy to init */ + aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.colorOutput = -1; + transform.maxInput = -1; + transform.maxGeneric = -1; + transform.colorTemp = -1; + transform.tmp0 = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = aa_transform_inst; + transform.base.transform_declaration = aa_transform_decl; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) aapoint_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(aapoint_fs.tokens, 0); +#endif + + aapoint_fs.input_semantic_name[aapoint_fs.num_inputs] = TGSI_SEMANTIC_GENERIC; + aapoint_fs.input_semantic_index[aapoint_fs.num_inputs] = transform.maxGeneric + 1; + aapoint_fs.num_inputs++; + + aapoint->fs->aapoint_fs + = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); + + /* advertise the extra post-transform vertex attributes which will have + * the texcoords. + */ + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = transform.maxGeneric + 1; +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) +{ + if (!aapoint->fs->aapoint_fs) { + generate_aapoint_fs(aapoint); + } + aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); +} + + + +static INLINE struct aapoint_stage * +aapoint_stage( struct draw_stage *stage ) +{ + return (struct aapoint_stage *) stage; +} + + +static void +passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw an AA point by drawing a quad. + */ +static void +aapoint_point(struct draw_stage *stage, struct prim_header *header) +{ + const struct aapoint_stage *aapoint = aapoint_stage(stage); + struct prim_header tri; + struct vertex_header *v[4]; + uint texPos = aapoint->tex_slot; + float radius, *pos, *tex; + uint i; + float k; + + if (aapoint->psize_slot >= 0) { + radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0]; + } + else { + radius = aapoint->radius; + } + + /* + * Note: the texcoords (generic attrib, really) we use are special: + * The S and T components simply vary from -1 to +1. + * The R component is k, below. + * The Q component is 1.0 and will used as a handy constant in the + * fragment shader. + */ + + /* + * k is the threshold distance from the point's center at which + * we begin alpha attenuation (the coverage value). + * Operating within a unit circle, we'll compute the fragment's + * distance 'd' from the center point using the texcoords. + * IF d > 1.0 THEN + * KILL fragment + * ELSE IF d > k THEN + * compute coverage in [0,1] proportional to d in [k, 1]. + * ELSE + * coverage = 1.0; // full coverage + * ENDIF + */ + +#if !NORMALIZE + k = 1.0 / radius; + k = 1.0 - 2.0 * k + k * k; +#else + k = 1.0 - 1.0 / radius; +#endif + + /* allocate/dup new verts */ + for (i = 0; i < 4; i++) { + v[i] = dup_vert(stage, header->v[0], i); + } + + /* new verts */ + pos = v[0]->data[0]; + pos[0] -= radius; + pos[1] -= radius; + + pos = v[1]->data[0]; + pos[0] += radius; + pos[1] -= radius; + + pos = v[2]->data[0]; + pos[0] += radius; + pos[1] += radius; + + pos = v[3]->data[0]; + pos[0] -= radius; + pos[1] += radius; + + /* new texcoords */ + tex = v[0]->data[texPos]; + ASSIGN_4V(tex, -1, -1, k, 1); + + tex = v[1]->data[texPos]; + ASSIGN_4V(tex, 1, -1, k, 1); + + tex = v[2]->data[texPos]; + ASSIGN_4V(tex, 1, 1, k, 1); + + tex = v[3]->data[texPos]; + ASSIGN_4V(tex, -1, 1, k, 1); + + /* emit 2 tris for the quad strip */ + tri.v[0] = v[0]; + tri.v[1] = v[1]; + tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[0]; + tri.v[1] = v[2]; + tri.v[2] = v[3]; + stage->next->tri( stage->next, &tri ); +} + + +static void +aapoint_first_point(struct draw_stage *stage, struct prim_header *header) +{ + auto struct aapoint_stage *aapoint = aapoint_stage(stage); + struct draw_context *draw = stage->draw; + + assert(draw->rasterizer->point_smooth); + + if (draw->rasterizer->point_size <= 2.0) + aapoint->radius = 1.0; + else + aapoint->radius = 0.5f * draw->rasterizer->point_size; + + aapoint->tex_slot = draw->num_vs_outputs; + assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ + draw->extra_vp_outputs.slot = aapoint->tex_slot; + + /* + * Bind our fragprog. + */ + bind_aapoint_fragment_shader(aapoint); + + /* find psize slot in post-transform vertex */ + aapoint->psize_slot = -1; + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->state->num_outputs; i++) { + if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + aapoint->psize_slot = i; + break; + } + } + } + + /* now really draw first line */ + stage->point = aapoint_point; + stage->point(stage, header); +} + + +static void +aapoint_flush(struct draw_stage *stage, unsigned flags) +{ + struct draw_context *draw = stage->draw; + struct aapoint_stage *aapoint = aapoint_stage(stage); + struct pipe_context *pipe = aapoint->pipe; + + stage->point = aapoint_first_point; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs); + + draw->extra_vp_outputs.slot = 0; +} + + +static void +aapoint_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +aapoint_destroy(struct draw_stage *stage) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct aapoint_stage * +draw_aapoint_stage(struct draw_context *draw) +{ + struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); + + draw_alloc_temp_verts( &aapoint->stage, 4 ); + + aapoint->stage.draw = draw; + aapoint->stage.next = NULL; + aapoint->stage.point = aapoint_first_point; + aapoint->stage.line = passthrough_line; + aapoint->stage.tri = passthrough_tri; + aapoint->stage.flush = aapoint_flush; + aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter; + aapoint->stage.destroy = aapoint_destroy; + + return aapoint; +} + + +/* + * XXX temporary? solution to mapping a pipe_context to a aapoint_stage. + */ + +#define MAX_CONTEXTS 10 + +static struct pipe_context *Pipe[MAX_CONTEXTS]; +static struct aapoint_stage *Stage[MAX_CONTEXTS]; +static uint NumContexts; + +static void +add_aa_pipe_context(struct pipe_context *pipe, struct aapoint_stage *aa) +{ + assert(NumContexts < MAX_CONTEXTS); + Pipe[NumContexts] = pipe; + Stage[NumContexts] = aa; + NumContexts++; +} + +static struct aapoint_stage * +aapoint_stage_from_pipe(struct pipe_context *pipe) +{ + uint i; + for (i = 0; i < NumContexts; i++) { + if (Pipe[i] == pipe) + return Stage[i]; + } + assert(0); + return NULL; +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +aapoint_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); + } + + return aafs; +} + + +static void +aapoint_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; + /* save current */ + aapoint->fs = aafs; + /* pass-through */ + aapoint->driver_bind_fs_state(aapoint->pipe, aafs->driver_fs); +} + + +static void +aapoint_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; + /* pass-through */ + aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs); + FREE(aafs); +} + + +/** + * Called by drivers that want to install this AA point prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA points. + */ +void +draw_install_aapoint_stage(struct draw_context *draw, + struct pipe_context *pipe) +{ + struct aapoint_stage *aapoint; + + /* + * Create / install AA point drawing / prim stage + */ + aapoint = draw_aapoint_stage( draw ); + assert(aapoint); + draw->pipeline.aapoint = &aapoint->stage; + + aapoint->pipe = pipe; + + /* save original driver functions */ + aapoint->driver_create_fs_state = pipe->create_fs_state; + aapoint->driver_bind_fs_state = pipe->bind_fs_state; + aapoint->driver_delete_fs_state = pipe->delete_fs_state; + + /* override the driver's functions */ + pipe->create_fs_state = aapoint_create_fs_state; + pipe->bind_fs_state = aapoint_bind_fs_state; + pipe->delete_fs_state = aapoint_delete_fs_state; + + add_aa_pipe_context(pipe, aapoint); +} diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b90a9f474d..c28e78d33a 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -105,6 +105,8 @@ void draw_destroy( struct draw_context *draw ) draw->pipeline.validate->destroy( draw->pipeline.validate ); if (draw->pipeline.aaline) draw->pipeline.aaline->destroy( draw->pipeline.aaline ); + if (draw->pipeline.aapoint) + draw->pipeline.aapoint->destroy( draw->pipeline.aapoint ); if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); tgsi_exec_machine_free_data(&draw->machine); diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 82035aa8ad..43b58bc056 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -99,6 +99,9 @@ boolean draw_use_sse(struct draw_context *draw); void draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); +void +draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe); + int draw_find_vs_output(struct draw_context *draw, diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 492c152ff9..8c469e74b7 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -180,6 +180,7 @@ struct draw_context struct draw_stage *offset; struct draw_stage *unfilled; struct draw_stage *stipple; + struct draw_stage *aapoint; struct draw_stage *aaline; struct draw_stage *wide; struct draw_stage *rasterize; diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 97e40e372b..5167ef1e75 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -63,6 +63,11 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.aaline; } + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) { + draw->pipeline.aapoint->next = next; + next = draw->pipeline.aapoint; + } + if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines && !draw->rasterizer->line_smooth) || (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 316020cba6..de4c6c18e7 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -328,8 +328,12 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, draw_set_rasterize_stage(softpipe->draw, softpipe->setup); } - /* enable aaline stage */ + /* plug in AA line/point stages */ draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); + draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); + + /* sp_prim_setup can do wide points (don't convert to quads) */ + draw_convert_wide_points(softpipe->draw, FALSE); sp_init_surface_functions(softpipe); -- cgit v1.2.3 From 446bfc32a83008e0865ec869bc80b920c907f10f Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Feb 2008 16:56:32 -0700 Subject: gallium: new draw stage for polygon stipple. For hardware without native polygon stipple. Create a 32x32 alpha texture that encodes the stipple pattern. Modify the user's fragment program to sample the texture (with gl_FragCoord) and kill the fragment according to the texel value. Temporarily enabled in softpipe driver, replacing the sp_quad_stipple.c step. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_context.h | 3 + src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_pstipple.c | 717 +++++++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_validate.c | 6 + src/gallium/drivers/softpipe/sp_context.c | 5 + src/gallium/drivers/softpipe/sp_context.h | 7 + src/gallium/drivers/softpipe/sp_quad.c | 2 + 8 files changed, 742 insertions(+) create mode 100644 src/gallium/auxiliary/draw/draw_pstipple.c (limited to 'src') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index b7e71ed3ec..c9980f0b83 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -16,6 +16,7 @@ C_SOURCES = \ draw_flatshade.c \ draw_offset.c \ draw_prim.c \ + draw_pstipple.c \ draw_stipple.c \ draw_twoside.c \ draw_unfilled.c \ diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 43b58bc056..c25301f71d 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -102,6 +102,9 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); void draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe); +void +draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe); + int draw_find_vs_output(struct draw_context *draw, diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 8c469e74b7..6abced139b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -182,6 +182,7 @@ struct draw_context struct draw_stage *stipple; struct draw_stage *aapoint; struct draw_stage *aaline; + struct draw_stage *pstipple; struct draw_stage *wide; struct draw_stage *rasterize; } pipeline; diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c new file mode 100644 index 0000000000..4048abf856 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pstipple.c @@ -0,0 +1,717 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Polygon stipple stage: implement polygon stipple with texture map and + * fragment program. The fragment program samples the texture and does + * a fragment kill for the stipple-failing fragments. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct pstip_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; + void *pstip_fs; +}; + + +/** + * Subclass of draw_stage + */ +struct pstip_stage +{ + struct draw_stage stage; + + void *sampler_cso; + struct pipe_texture *texture; + uint sampler_unit; + + /* + * Currently bound state + */ + struct pstip_fragment_shader *fs; + struct { + void *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + const struct pipe_poly_stipple *stipple; + } state; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *); + + void (*driver_set_sampler_texture)(struct pipe_context *, + unsigned sampler, + struct pipe_texture *); + + void (*driver_set_polygon_stipple)(struct pipe_context *, + const struct pipe_poly_stipple *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct pstip_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int wincoordInput; + int maxInput; + int maxSampler; /**< max sampler index found */ + int texTemp; /**< temp registers */ + int numImmed; + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +pstip_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + if ((int) decl->u.DeclarationRange.Last > pctx->maxSampler) + pctx->maxSampler = (int) decl->u.DeclarationRange.Last; + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + pctx->maxInput = MAX2(pctx->maxInput, decl->u.DeclarationRange.Last); + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) + pctx->wincoordInput = (int) decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + pctx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +static void +pstip_transform_immed(struct tgsi_transform_context *ctx, + struct tgsi_full_immediate *immed) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + pctx->numImmed++; +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +pstip_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + + if (pctx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction newInst; + uint i; + int wincoordInput; + const int sampler = pctx->maxSampler + 1; + + if (pctx->wincoordInput < 0) + wincoordInput = pctx->maxInput + 1; + else + wincoordInput = pctx->wincoordInput; + + /* find one free temp reg */ + for (i = 0; i < 32; i++) { + if ((pctx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (pctx->texTemp < 0) + pctx->texTemp = i; + else + break; + } + } + assert(pctx->texTemp >= 0); + + if (pctx->wincoordInput < 0) { + /* declare new position input reg */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; + decl.Semantic.SemanticIndex = 0; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = wincoordInput; + ctx->emit_declaration(ctx, &decl); + } + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = sampler; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = pctx->texTemp; + ctx->emit_declaration(ctx, &decl); + + /* emit immediate = {1/32, 1/32, 1, 1} + * The index/position of this immediate will be pctx->numImmed + */ + { + static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; + struct tgsi_full_immediate immed; + uint size = 4; + immed = tgsi_default_full_immediate(); + immed.Immediate.Size = 1 + size; /* one for the token itself */ + immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value; + ctx->emit_immediate(ctx, &immed); + } + + pctx->firstInstruction = FALSE; + + + /* + * Insert new MUL/TEX/KILP instructions at start of program + * Take gl_FragCoord, divide by 32 (stipple size), sample the + * texture and kill fragment if needed. + * + * We'd like to use non-normalized texcoords to index into a RECT + * texture, but we can only use GL_REPEAT wrap mode with normalized + * texcoords. Darn. + */ + + /* MUL texTemp, INPUT[wincoord], 1/32; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE; + newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed; + ctx->emit_instruction(ctx, &newInst); + + /* TEX texTemp, texTemp, sampler; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + newInst.FullSrcRegisters[1].SrcRegister.Index = sampler; + ctx->emit_instruction(ctx, &newInst); + + /* KILP texTemp; # if texTemp < 0, KILL fragment */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + } + + /* emit this instruction */ + ctx->emit_instruction(ctx, inst); +} + + +/** + * Generate the frag shader we'll use for doing polygon stipple. + * This will be the user's shader prefixed with a TEX and KIL instruction. + */ +static void +generate_pstip_fs(struct pstip_stage *pstip) +{ + const struct pipe_shader_state *orig_fs = &pstip->fs->state; + /*struct draw_context *draw = pstip->stage.draw;*/ + struct pipe_shader_state pstip_fs; + struct pstip_transform_context transform; + +#define MAX 1000 + + pstip_fs = *orig_fs; /* copy to init */ + pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.wincoordInput = -1; + transform.maxInput = -1; + transform.maxSampler = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = pstip_transform_inst; + transform.base.transform_declaration = pstip_transform_decl; + transform.base.transform_immediate = pstip_transform_immed; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) pstip_fs.tokens, + MAX, &transform.base); + +#if 1 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(pstip_fs.tokens, 0); +#endif + + pstip->sampler_unit = transform.maxSampler + 1; + + if (transform.wincoordInput < 0) { + pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION; + pstip_fs.input_semantic_index[pstip_fs.num_inputs] = transform.maxInput; + pstip_fs.num_inputs++; + } + + pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); +} + + +/** + * Load texture image with current stipple pattern. + */ +static void +pstip_update_texture(struct pstip_stage *pstip) +{ + static const uint bit31 = 1 << 31; + struct pipe_context *pipe = pstip->pipe; + struct pipe_surface *surface; + const uint *stipple = pstip->state.stipple->stipple; + uint i, j; + ubyte *data; + + surface = pipe->get_tex_surface(pipe, pstip->texture, 0, 0, 0); + data = pipe_surface_map(surface); + + /* + * Load alpha texture. + * Note: 0 means keep the fragment, 255 means kill it. + * We'll negate the texel value and use KILP which kills if value + * is negative. + */ + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + if (stipple[i] & (bit31 >> j)) { + /* fragment "on" */ + data[i * surface->pitch + j] = 0; + } + else { + /* fragment "off" */ + data[i * surface->pitch + j] = 255; + } + } + } + + /* unmap */ + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, pstip->texture); +} + + +/** + * Create the texture map we'll use for stippling. + */ +static void +pstip_create_texture(struct pstip_stage *pstip) +{ + struct pipe_context *pipe = pstip->pipe; + struct pipe_texture texTemp; + + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.last_level = 0; + texTemp.width[0] = 32; + texTemp.height[0] = 32; + texTemp.depth[0] = 1; + texTemp.cpp = 1; + + pstip->texture = pipe->texture_create(pipe, &texTemp); + + //pstip_update_texture(pstip); +} + + +/** + * Create the sampler CSO that'll be used for antialiasing. + * By using a mipmapped texture, we don't have to generate a different + * texture image for each line size. + */ +static void +pstip_create_sampler(struct pstip_stage *pstip) +{ + struct pipe_sampler_state sampler; + struct pipe_context *pipe = pstip->pipe; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.normalized_coords = 1; + sampler.min_lod = 0.0f; + sampler.max_lod = 0.0f; + + pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_pstip_fragment_shader(struct pstip_stage *pstip) +{ + if (!pstip->fs->pstip_fs) { + generate_pstip_fs(pstip); + } + pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); +} + + + +static INLINE struct pstip_stage * +pstip_stage( struct draw_stage *stage ) +{ + return (struct pstip_stage *) stage; +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + + +static void +passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + + +static void +pstip_first_tri(struct draw_stage *stage, struct prim_header *header) +{ + struct pstip_stage *pstip = pstip_stage(stage); + struct draw_context *draw = stage->draw; + struct pipe_context *pipe = pstip->pipe; + + assert(draw->rasterizer->poly_stipple_enable); + + /* + * Bind our fragprog, sampler and texture + */ + bind_pstip_fragment_shader(pstip); + + pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, pstip->sampler_cso); + pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, pstip->texture); + + /* now really draw first line */ + stage->tri = passthrough_tri; + stage->tri(stage, header); +} + + +static void +pstip_flush(struct draw_stage *stage, unsigned flags) +{ + /*struct draw_context *draw = stage->draw;*/ + struct pstip_stage *pstip = pstip_stage(stage); + struct pipe_context *pipe = pstip->pipe; + + stage->tri = pstip_first_tri; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); + + /* XXX restore original texture, sampler state */ + pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, + pstip->state.sampler[pstip->sampler_unit]); + pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, + pstip->state.texture[pstip->sampler_unit]); +} + + +static void +pstip_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +pstip_destroy(struct draw_stage *stage) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct pstip_stage * +draw_pstip_stage(struct draw_context *draw) +{ + struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage); + + draw_alloc_temp_verts( &pstip->stage, 8 ); + + pstip->stage.draw = draw; + pstip->stage.next = NULL; + pstip->stage.point = passthrough_point; + pstip->stage.line = passthrough_line; + pstip->stage.tri = pstip_first_tri; + pstip->stage.flush = pstip_flush; + pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; + pstip->stage.destroy = pstip_destroy; + + return pstip; +} + + +/* + * XXX temporary? solution to mapping a pipe_context to a pstip_stage. + */ + +#define MAX_CONTEXTS 10 + +static struct pipe_context *Pipe[MAX_CONTEXTS]; +static struct pstip_stage *Stage[MAX_CONTEXTS]; +static uint NumContexts; + +static void +add_pstip_pipe_context(struct pipe_context *pipe, struct pstip_stage *pstip) +{ + assert(NumContexts < MAX_CONTEXTS); + Pipe[NumContexts] = pipe; + Stage[NumContexts] = pstip; + NumContexts++; +} + +static struct pstip_stage * +pstip_stage_from_pipe(struct pipe_context *pipe) +{ + uint i; + for (i = 0; i < NumContexts; i++) { + if (Pipe[i] == pipe) + return Stage[i]; + } + assert(0); + return NULL; +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +pstip_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs); + } + + return aafs; +} + + +static void +pstip_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; + /* save current */ + pstip->fs = aafs; + /* pass-through */ + pstip->driver_bind_fs_state(pstip->pipe, aafs->driver_fs); +} + + +static void +pstip_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; + /* pass-through */ + pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs); + FREE(aafs); +} + + +static void +pstip_bind_sampler_state(struct pipe_context *pipe, + unsigned unit, void *sampler) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ + pstip->state.sampler[unit] = sampler; + /* pass-through */ + pstip->driver_bind_sampler_state(pstip->pipe, unit, sampler); +} + + +static void +pstip_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, struct pipe_texture *texture) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ + pstip->state.texture[sampler] = texture; + /* pass-through */ + pstip->driver_set_sampler_texture(pstip->pipe, sampler, texture); +} + + +static void +pstip_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ + pstip->state.stipple = stipple; + /* pass-through */ + pstip->driver_set_polygon_stipple(pstip->pipe, stipple); + + pstip_update_texture(pstip); +} + + + +/** + * Called by drivers that want to install this AA line prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA lines. + */ +void +draw_install_pstipple_stage(struct draw_context *draw, + struct pipe_context *pipe) +{ + struct pstip_stage *pstip; + + /* + * Create / install AA line drawing / prim stage + */ + pstip = draw_pstip_stage( draw ); + assert(pstip); + draw->pipeline.pstipple = &pstip->stage; + + pstip->pipe = pipe; + + /* create special texture, sampler state */ + pstip_create_texture(pstip); + pstip_create_sampler(pstip); + + /* save original driver functions */ + pstip->driver_create_fs_state = pipe->create_fs_state; + pstip->driver_bind_fs_state = pipe->bind_fs_state; + pstip->driver_delete_fs_state = pipe->delete_fs_state; + + pstip->driver_bind_sampler_state = pipe->bind_sampler_state; + pstip->driver_set_sampler_texture = pipe->set_sampler_texture; + pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; + + /* override the driver's functions */ + pipe->create_fs_state = pstip_create_fs_state; + pipe->bind_fs_state = pstip_bind_fs_state; + pipe->delete_fs_state = pstip_delete_fs_state; + + pipe->bind_sampler_state = pstip_bind_sampler_state; + pipe->set_sampler_texture = pstip_set_sampler_texture; + pipe->set_polygon_stipple = pstip_set_polygon_stipple; + + add_pstip_pipe_context(pipe, pstip); +} diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c index 5167ef1e75..efd6793f2b 100644 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ b/src/gallium/auxiliary/draw/draw_validate.c @@ -82,6 +82,12 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) precalc_flat = 1; /* only needed for lines really */ } + if (draw->rasterizer->poly_stipple_enable + && draw->pipeline.pstipple) { + draw->pipeline.pstipple->next = next; + next = draw->pipeline.pstipple; + } + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { draw->pipeline.unfilled->next = next; diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index de4c6c18e7..2cdf3c75bf 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -332,6 +332,11 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); +#if USE_DRAW_STAGE_PSTIPPLE + /* Do polygon stipple w/ texture map + frag prog? */ + draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); +#endif + /* sp_prim_setup can do wide points (don't convert to quads) */ draw_convert_wide_points(softpipe->draw, FALSE); diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index a50cee7648..feeafc7084 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -39,6 +39,13 @@ #include "sp_quad.h" +/** + * This is a temporary variable for testing draw-stage polygon stipple. + * If zero, do stipple in sp_quad_stipple.c + */ +#define USE_DRAW_STAGE_PSTIPPLE 1 + + struct softpipe_winsys; struct softpipe_vbuf_render; struct draw_context; diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c index 6bd468a51c..15b5594547 100644 --- a/src/gallium/drivers/softpipe/sp_quad.c +++ b/src/gallium/drivers/softpipe/sp_quad.c @@ -112,7 +112,9 @@ sp_build_quad_pipeline(struct softpipe_context *sp) sp_push_quad_first( sp, sp->quad.earlyz ); } +#if !USE_DRAW_STAGE_PSTIPPLE if (sp->rasterizer->poly_stipple_enable) { sp_push_quad_first( sp, sp->quad.polygon_stipple ); } +#endif } -- cgit v1.2.3