summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r--src/gallium/auxiliary/Makefile181
-rw-r--r--src/gallium/auxiliary/SConscript185
-rw-r--r--src/gallium/auxiliary/cso_cache/Makefile11
-rw-r--r--src/gallium/auxiliary/cso_cache/SConscript11
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c40
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h7
-rw-r--r--src/gallium/auxiliary/draw/Makefile46
-rw-r--r--src/gallium/auxiliary/draw/SConscript46
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c77
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h27
-rw-r--r--src/gallium/auxiliary/draw/draw_gs.c338
-rw-r--r--src/gallium/auxiliary/draw/draw_gs.h76
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c12
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aapoint.c12
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_clip.c42
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_cull.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_offset.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_stipple.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_vbuf.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_line.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_point.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h36
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c29
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c45
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c64
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_post_vs.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_util.c16
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.h1
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_ppc.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_varient.c15
-rw-r--r--src/gallium/auxiliary/gallivm/Makefile92
-rw-r--r--src/gallium/auxiliary/gallivm/SConscript16
-rw-r--r--src/gallium/auxiliary/gallivm/tgsitollvm.cpp4
-rw-r--r--src/gallium/auxiliary/indices/Makefile16
-rw-r--r--src/gallium/auxiliary/indices/SConscript28
-rw-r--r--src/gallium/auxiliary/pipebuffer/Makefile19
-rw-r--r--src/gallium/auxiliary/pipebuffer/SConscript19
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c278
-rw-r--r--src/gallium/auxiliary/rbug/Makefile14
-rw-r--r--src/gallium/auxiliary/rbug/SConscript14
-rw-r--r--src/gallium/auxiliary/rbug/rbug_context.h2
-rw-r--r--src/gallium/auxiliary/rbug/rbug_proto.h2
-rw-r--r--src/gallium/auxiliary/rtasm/Makefile13
-rw-r--r--src/gallium/auxiliary/rtasm/SConscript13
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_execmem.c32
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.c7
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.h1
-rw-r--r--src/gallium/auxiliary/sct/Makefile9
-rw-r--r--src/gallium/auxiliary/sct/SConscript9
-rw-r--r--src/gallium/auxiliary/sct/sct.c453
-rw-r--r--src/gallium/auxiliary/sct/sct.h123
-rw-r--r--src/gallium/auxiliary/sct/usage.c61
-rw-r--r--src/gallium/auxiliary/tgsi/Makefile22
-rw-r--r--src/gallium/auxiliary/tgsi/SConscript23
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c94
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c2229
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h58
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c30
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h23
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c22
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ppc.c3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c292
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_scan.c4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sse2.c66
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c380
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c188
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h100
-rw-r--r--src/gallium/auxiliary/translate/Makefile12
-rw-r--r--src/gallium/auxiliary/translate/SConscript12
-rw-r--r--src/gallium/auxiliary/translate/translate.h18
-rw-r--r--src/gallium/auxiliary/translate/translate_generic.c40
-rw-r--r--src/gallium/auxiliary/translate/translate_sse.c186
-rw-r--r--src/gallium/auxiliary/util/Makefile48
-rw-r--r--src/gallium/auxiliary/util/SConscript61
-rw-r--r--src/gallium/auxiliary/util/u_bitmask.c32
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c195
-rw-r--r--src/gallium/auxiliary/util/u_debug.c6
-rw-r--r--src/gallium/auxiliary/util/u_debug.h2
-rw-r--r--src/gallium/auxiliary/util/u_debug_dump.c6
-rw-r--r--src/gallium/auxiliary/util/u_debug_memory.c8
-rw-r--r--src/gallium/auxiliary/util/u_dl.h12
-rw-r--r--src/gallium/auxiliary/util/u_format.csv22
-rw-r--r--src/gallium/auxiliary/util/u_format.h2
-rw-r--r--src/gallium/auxiliary/util/u_math.h5
-rw-r--r--src/gallium/auxiliary/util/u_network.c8
-rw-r--r--src/gallium/auxiliary/util/u_network.h2
-rw-r--r--src/gallium/auxiliary/util/u_prim.h33
-rw-r--r--src/gallium/auxiliary/util/u_rect.c10
-rw-r--r--src/gallium/auxiliary/util/u_rect.h2
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c22
-rw-r--r--src/gallium/auxiliary/util/u_stream_stdc.c2
-rw-r--r--src/gallium/auxiliary/util/u_tile.c27
-rw-r--r--src/gallium/auxiliary/vl/Makefile13
-rw-r--r--src/gallium/auxiliary/vl/SConscript13
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c11
101 files changed, 3997 insertions, 2956 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 5446eb68a9..e3af41c6e0 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -1,12 +1,177 @@
-# src/gallium/auxiliary/Makefile
TOP = ../../..
include $(TOP)/configs/current
-SUBDIRS = $(GALLIUM_AUXILIARY_DIRS)
+LIBNAME = gallium
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
+C_SOURCES = \
+ cso_cache/cso_context.c \
+ cso_cache/cso_cache.c \
+ cso_cache/cso_hash.c \
+ draw/draw_context.c \
+ draw/draw_gs.c \
+ draw/draw_pipe.c \
+ draw/draw_pipe_aaline.c \
+ draw/draw_pipe_aapoint.c \
+ draw/draw_pipe_clip.c \
+ draw/draw_pipe_cull.c \
+ draw/draw_pipe_flatshade.c \
+ draw/draw_pipe_offset.c \
+ draw/draw_pipe_pstipple.c \
+ draw/draw_pipe_stipple.c \
+ draw/draw_pipe_twoside.c \
+ draw/draw_pipe_unfilled.c \
+ draw/draw_pipe_util.c \
+ draw/draw_pipe_validate.c \
+ draw/draw_pipe_vbuf.c \
+ draw/draw_pipe_wide_line.c \
+ draw/draw_pipe_wide_point.c \
+ draw/draw_pt.c \
+ draw/draw_pt_elts.c \
+ draw/draw_pt_emit.c \
+ draw/draw_pt_fetch.c \
+ draw/draw_pt_fetch_emit.c \
+ draw/draw_pt_fetch_shade_emit.c \
+ draw/draw_pt_fetch_shade_pipeline.c \
+ draw/draw_pt_post_vs.c \
+ draw/draw_pt_util.c \
+ draw/draw_pt_varray.c \
+ draw/draw_pt_vcache.c \
+ draw/draw_vertex.c \
+ draw/draw_vs.c \
+ draw/draw_vs_varient.c \
+ draw/draw_vs_aos.c \
+ draw/draw_vs_aos_io.c \
+ draw/draw_vs_aos_machine.c \
+ draw/draw_vs_exec.c \
+ draw/draw_vs_llvm.c \
+ draw/draw_vs_ppc.c \
+ draw/draw_vs_sse.c \
+ indices/u_indices_gen.c \
+ indices/u_unfilled_gen.c \
+ pipebuffer/pb_buffer_fenced.c \
+ pipebuffer/pb_buffer_malloc.c \
+ pipebuffer/pb_bufmgr_alt.c \
+ pipebuffer/pb_bufmgr_cache.c \
+ pipebuffer/pb_bufmgr_debug.c \
+ pipebuffer/pb_bufmgr_fenced.c \
+ pipebuffer/pb_bufmgr_mm.c \
+ pipebuffer/pb_bufmgr_ondemand.c \
+ pipebuffer/pb_bufmgr_pool.c \
+ pipebuffer/pb_bufmgr_slab.c \
+ pipebuffer/pb_validate.c \
+ rbug/rbug_connection.c \
+ rbug/rbug_core.c \
+ rbug/rbug_texture.c \
+ rbug/rbug_context.c \
+ rbug/rbug_shader.c \
+ rbug/rbug_demarshal.c \
+ rtasm/rtasm_cpu.c \
+ rtasm/rtasm_execmem.c \
+ rtasm/rtasm_x86sse.c \
+ rtasm/rtasm_ppc.c \
+ rtasm/rtasm_ppc_spe.c \
+ tgsi/tgsi_sanity.c \
+ tgsi/tgsi_build.c \
+ tgsi/tgsi_dump.c \
+ tgsi/tgsi_exec.c \
+ tgsi/tgsi_info.c \
+ tgsi/tgsi_iterate.c \
+ tgsi/tgsi_parse.c \
+ tgsi/tgsi_ppc.c \
+ tgsi/tgsi_scan.c \
+ tgsi/tgsi_sse2.c \
+ tgsi/tgsi_text.c \
+ tgsi/tgsi_transform.c \
+ tgsi/tgsi_ureg.c \
+ tgsi/tgsi_util.c \
+ translate/translate_generic.c \
+ translate/translate_sse.c \
+ translate/translate.c \
+ translate/translate_cache.c \
+ util/u_debug.c \
+ util/u_debug_dump.c \
+ util/u_debug_symbol.c \
+ util/u_debug_stack.c \
+ util/u_blit.c \
+ util/u_blitter.c \
+ util/u_cache.c \
+ util/u_cpu_detect.c \
+ util/u_dl.c \
+ util/u_draw_quad.c \
+ util/u_format.c \
+ util/u_format_access.c \
+ util/u_format_table.c \
+ util/u_gen_mipmap.c \
+ util/u_handle_table.c \
+ util/u_hash_table.c \
+ util/u_hash.c \
+ util/u_keymap.c \
+ util/u_linear.c \
+ util/u_network.c \
+ util/u_math.c \
+ util/u_mm.c \
+ util/u_rect.c \
+ util/u_simple_shaders.c \
+ util/u_snprintf.c \
+ util/u_stream_stdc.c \
+ util/u_stream_wd.c \
+ util/u_surface.c \
+ util/u_texture.c \
+ util/u_tile.c \
+ util/u_time.c \
+ util/u_timed_winsys.c \
+ util/u_upload_mgr.c \
+ util/u_simple_screen.c \
+ vl/vl_bitstream_parser.c \
+ vl/vl_mpeg12_mc_renderer.c \
+ vl/vl_compositor.c \
+ vl/vl_csc.c \
+ vl/vl_shader_build.c
+
+GALLIVM_SOURCES = \
+ gallivm/gallivm.cpp \
+ gallivm/gallivm_cpu.cpp \
+ gallivm/instructions.cpp \
+ gallivm/loweringpass.cpp \
+ gallivm/tgsitollvm.cpp \
+ gallivm/storage.cpp \
+ gallivm/storagesoa.cpp \
+ gallivm/instructionssoa.cpp
+
+INC_SOURCES = \
+ gallivm/gallivm_builtins.cpp \
+ gallivm/gallivmsoabuiltins.cpp
+
+# XXX: gallivm doesn't build correctly so disable for now
+#ifeq ($(MESA_LLVM),1)
+#DEFINES += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
+#CPP_SOURCES += \
+# $(GALLIVM_SOURCES)
+#endif
+
+
+include ../Makefile.template
+
+
+gallivm/gallivm_builtins.cpp: gallivm/llvm_builtins.c
+ clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp1.bin
+ (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
+ rm temp1.bin
+
+gallivm/gallivmsoabuiltins.cpp: gallivm/soabuiltins.c
+ clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin
+ (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
+ rm temp2.bin
+
+
+indices/u_indices_gen.c: indices/u_indices_gen.py
+ python $< > $@
+
+indices/u_unfilled_gen.c: indices/u_unfilled_gen.py
+ python $< > $@
+
+util/u_format_table.c: util/u_format_table.py util/u_format_parse.py util/u_format.csv
+ python util/u_format_table.py util/u_format.csv > $@
+
+util/u_format_access.c: util/u_format_access.py util/u_format_parse.py util/u_format.csv
+ python util/u_format_access.py util/u_format.csv > $@
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
new file mode 100644
index 0000000000..782eb53386
--- /dev/null
+++ b/src/gallium/auxiliary/SConscript
@@ -0,0 +1,185 @@
+Import('*')
+
+from sys import executable as python_cmd
+
+env.Append(CPPPATH = [
+ 'indices',
+ 'util',
+])
+
+env.CodeGenerate(
+ target = 'indices/u_indices_gen.c',
+ script = 'indices/u_indices_gen.py',
+ source = [],
+ command = python_cmd + ' $SCRIPT > $TARGET'
+)
+
+env.CodeGenerate(
+ target = 'indices/u_unfilled_gen.c',
+ script = 'indices/u_unfilled_gen.py',
+ source = [],
+ command = python_cmd + ' $SCRIPT > $TARGET'
+)
+
+env.CodeGenerate(
+ target = 'util/u_format_table.c',
+ script = 'util/u_format_table.py',
+ source = ['util/u_format.csv'],
+ command = 'python $SCRIPT $SOURCE > $TARGET'
+)
+
+env.CodeGenerate(
+ target = 'util/u_format_access.c',
+ script = 'util/u_format_access.py',
+ source = ['util/u_format.csv'],
+ command = 'python $SCRIPT $SOURCE > $TARGET'
+)
+
+source = [
+ 'cso_cache/cso_context.c',
+ 'cso_cache/cso_cache.c',
+ 'cso_cache/cso_hash.c',
+ 'draw/draw_context.c',
+ 'draw/draw_pipe.c',
+ 'draw/draw_pipe_aaline.c',
+ 'draw/draw_pipe_aapoint.c',
+ 'draw/draw_pipe_clip.c',
+ 'draw/draw_pipe_cull.c',
+ 'draw/draw_pipe_flatshade.c',
+ 'draw/draw_pipe_offset.c',
+ 'draw/draw_pipe_pstipple.c',
+ 'draw/draw_pipe_stipple.c',
+ 'draw/draw_pipe_twoside.c',
+ 'draw/draw_pipe_unfilled.c',
+ 'draw/draw_pipe_util.c',
+ 'draw/draw_pipe_validate.c',
+ 'draw/draw_pipe_vbuf.c',
+ 'draw/draw_pipe_wide_line.c',
+ 'draw/draw_pipe_wide_point.c',
+ 'draw/draw_pt.c',
+ 'draw/draw_pt_elts.c',
+ 'draw/draw_pt_emit.c',
+ 'draw/draw_pt_fetch.c',
+ 'draw/draw_pt_fetch_emit.c',
+ 'draw/draw_pt_fetch_shade_emit.c',
+ 'draw/draw_pt_fetch_shade_pipeline.c',
+ 'draw/draw_pt_post_vs.c',
+ 'draw/draw_pt_util.c',
+ 'draw/draw_pt_varray.c',
+ 'draw/draw_pt_vcache.c',
+ 'draw/draw_vertex.c',
+ 'draw/draw_vs.c',
+ 'draw/draw_vs_aos.c',
+ 'draw/draw_vs_aos_io.c',
+ 'draw/draw_vs_aos_machine.c',
+ 'draw/draw_vs_exec.c',
+ 'draw/draw_vs_llvm.c',
+ 'draw/draw_vs_ppc.c',
+ 'draw/draw_vs_sse.c',
+ 'draw/draw_vs_varient.c',
+ 'draw/draw_gs.c',
+ #'indices/u_indices.c',
+ #'indices/u_unfilled_indices.c',
+ 'indices/u_indices_gen.c',
+ 'indices/u_unfilled_gen.c',
+ 'pipebuffer/pb_buffer_fenced.c',
+ 'pipebuffer/pb_buffer_malloc.c',
+ 'pipebuffer/pb_bufmgr_alt.c',
+ 'pipebuffer/pb_bufmgr_cache.c',
+ 'pipebuffer/pb_bufmgr_debug.c',
+ 'pipebuffer/pb_bufmgr_fenced.c',
+ 'pipebuffer/pb_bufmgr_mm.c',
+ 'pipebuffer/pb_bufmgr_ondemand.c',
+ 'pipebuffer/pb_bufmgr_pool.c',
+ 'pipebuffer/pb_bufmgr_slab.c',
+ 'pipebuffer/pb_validate.c',
+ 'rbug/rbug_core.c',
+ 'rbug/rbug_shader.c',
+ 'rbug/rbug_context.c',
+ 'rbug/rbug_texture.c',
+ 'rbug/rbug_demarshal.c',
+ 'rbug/rbug_connection.c',
+ 'rtasm/rtasm_cpu.c',
+ 'rtasm/rtasm_execmem.c',
+ 'rtasm/rtasm_x86sse.c',
+ 'rtasm/rtasm_ppc.c',
+ 'rtasm/rtasm_ppc_spe.c',
+ 'tgsi/tgsi_build.c',
+ 'tgsi/tgsi_dump.c',
+ 'tgsi/tgsi_dump_c.c',
+ 'tgsi/tgsi_exec.c',
+ 'tgsi/tgsi_info.c',
+ 'tgsi/tgsi_iterate.c',
+ 'tgsi/tgsi_parse.c',
+ 'tgsi/tgsi_sanity.c',
+ 'tgsi/tgsi_scan.c',
+ 'tgsi/tgsi_ppc.c',
+ 'tgsi/tgsi_sse2.c',
+ 'tgsi/tgsi_text.c',
+ 'tgsi/tgsi_transform.c',
+ 'tgsi/tgsi_ureg.c',
+ 'tgsi/tgsi_util.c',
+ 'translate/translate_generic.c',
+ 'translate/translate_sse.c',
+ 'translate/translate.c',
+ 'translate/translate_cache.c',
+ 'util/u_bitmask.c',
+ 'util/u_blit.c',
+ 'util/u_blitter.c',
+ 'util/u_cache.c',
+ 'util/u_cpu_detect.c',
+ 'util/u_debug.c',
+ 'util/u_debug_dump.c',
+ 'util/u_debug_memory.c',
+ 'util/u_debug_stack.c',
+ 'util/u_debug_symbol.c',
+ 'util/u_dl.c',
+ 'util/u_draw_quad.c',
+ 'util/u_format.c',
+ 'util/u_format_access.c',
+ 'util/u_format_table.c',
+ 'util/u_gen_mipmap.c',
+ 'util/u_handle_table.c',
+ 'util/u_hash.c',
+ 'util/u_hash_table.c',
+ 'util/u_keymap.c',
+ 'util/u_network.c',
+ 'util/u_math.c',
+ 'util/u_mm.c',
+ 'util/u_rect.c',
+ 'util/u_simple_shaders.c',
+ 'util/u_snprintf.c',
+ 'util/u_stream_stdc.c',
+ 'util/u_stream_wd.c',
+ 'util/u_surface.c',
+ 'util/u_texture.c',
+ 'util/u_tile.c',
+ 'util/u_time.c',
+ 'util/u_timed_winsys.c',
+ 'util/u_upload_mgr.c',
+ 'util/u_simple_screen.c',
+ 'vl/vl_bitstream_parser.c',
+ 'vl/vl_mpeg12_mc_renderer.c',
+ 'vl/vl_compositor.c',
+ 'vl/vl_csc.c',
+ 'vl/vl_shader_build.c',
+]
+
+if env['llvm']:
+ source += [
+ 'gallivm/gallivm.cpp',
+ 'gallivm/gallivm_cpu.cpp',
+ 'gallivm/instructions.cpp',
+ 'gallivm/loweringpass.cpp',
+ 'gallivm/tgsitollvm.cpp',
+ 'gallivm/storage.cpp',
+ 'gallivm/storagesoa.cpp',
+ 'gallivm/instructionssoa.cpp',
+ ]
+
+gallium = env.ConvenienceLibrary(
+ target = 'gallium',
+ source = source,
+)
+
+Export('gallium')
diff --git a/src/gallium/auxiliary/cso_cache/Makefile b/src/gallium/auxiliary/cso_cache/Makefile
deleted file mode 100644
index 8726afcd94..0000000000
--- a/src/gallium/auxiliary/cso_cache/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = cso_cache
-
-C_SOURCES = \
- cso_context.c \
- cso_cache.c \
- cso_hash.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/cso_cache/SConscript b/src/gallium/auxiliary/cso_cache/SConscript
deleted file mode 100644
index 651e68a191..0000000000
--- a/src/gallium/auxiliary/cso_cache/SConscript
+++ /dev/null
@@ -1,11 +0,0 @@
-Import('*')
-
-cso_cache = env.ConvenienceLibrary(
- target = 'cso_cache',
- source = [
- 'cso_context.c',
- 'cso_cache.c',
- 'cso_hash.c',
- ])
-
-auxiliaries.insert(0, cso_cache)
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 80bd0c91db..2b16332e14 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -42,6 +42,7 @@
#include "cso_cache/cso_context.h"
#include "cso_cache/cso_cache.h"
#include "cso_cache/cso_hash.h"
+#include "cso_context.h"
struct cso_context {
struct pipe_context *pipe;
@@ -85,8 +86,8 @@ struct cso_context {
void *blend, *blend_saved;
void *depth_stencil, *depth_stencil_saved;
void *rasterizer, *rasterizer_saved;
- void *fragment_shader, *fragment_shader_saved;
- void *vertex_shader, *vertex_shader_saved;
+ void *fragment_shader, *fragment_shader_saved, *geometry_shader;
+ void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved;
struct pipe_framebuffer_state fb, fb_saved;
struct pipe_viewport_state vp, vp_saved;
@@ -1027,3 +1028,38 @@ enum pipe_error cso_set_blend_color(struct cso_context *ctx,
}
return PIPE_OK;
}
+
+enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
+ void *handle)
+{
+ if (ctx->geometry_shader != handle) {
+ ctx->geometry_shader = handle;
+ ctx->pipe->bind_gs_state(ctx->pipe, handle);
+ }
+ return PIPE_OK;
+}
+
+void cso_delete_geometry_shader(struct cso_context *ctx, void *handle)
+{
+ if (handle == ctx->geometry_shader) {
+ /* unbind before deleting */
+ ctx->pipe->bind_gs_state(ctx->pipe, NULL);
+ ctx->geometry_shader = NULL;
+ }
+ ctx->pipe->delete_gs_state(ctx->pipe, handle);
+}
+
+void cso_save_geometry_shader(struct cso_context *ctx)
+{
+ assert(!ctx->geometry_shader_saved);
+ ctx->geometry_shader_saved = ctx->geometry_shader;
+}
+
+void cso_restore_geometry_shader(struct cso_context *ctx)
+{
+ if (ctx->geometry_shader_saved != ctx->geometry_shader) {
+ ctx->pipe->bind_gs_state(ctx->pipe, ctx->geometry_shader_saved);
+ ctx->geometry_shader = ctx->geometry_shader_saved;
+ }
+ ctx->geometry_shader_saved = NULL;
+}
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index e5b92177cf..b9e313e32d 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -146,6 +146,13 @@ void cso_save_vertex_shader(struct cso_context *cso);
void cso_restore_vertex_shader(struct cso_context *cso);
+enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
+ void *handle);
+void cso_delete_geometry_shader(struct cso_context *ctx, void *handle);
+void cso_save_geometry_shader(struct cso_context *cso);
+void cso_restore_geometry_shader(struct cso_context *cso);
+
+
enum pipe_error cso_set_framebuffer(struct cso_context *cso,
const struct pipe_framebuffer_state *fb);
diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile
deleted file mode 100644
index 5041dcc072..0000000000
--- a/src/gallium/auxiliary/draw/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = draw
-
-C_SOURCES = \
- draw_context.c \
- draw_pipe.c \
- draw_pipe_aaline.c \
- draw_pipe_aapoint.c \
- draw_pipe_clip.c \
- draw_pipe_cull.c \
- draw_pipe_flatshade.c \
- draw_pipe_offset.c \
- draw_pipe_pstipple.c \
- draw_pipe_stipple.c \
- draw_pipe_twoside.c \
- draw_pipe_unfilled.c \
- draw_pipe_util.c \
- draw_pipe_validate.c \
- draw_pipe_vbuf.c \
- draw_pipe_wide_line.c \
- draw_pipe_wide_point.c \
- draw_pt.c \
- draw_pt_elts.c \
- draw_pt_emit.c \
- draw_pt_fetch.c \
- draw_pt_fetch_emit.c \
- draw_pt_fetch_shade_emit.c \
- draw_pt_fetch_shade_pipeline.c \
- draw_pt_post_vs.c \
- draw_pt_util.c \
- draw_pt_varray.c \
- draw_pt_vcache.c \
- draw_vertex.c \
- draw_vs.c \
- draw_vs_varient.c \
- draw_vs_aos.c \
- draw_vs_aos_io.c \
- draw_vs_aos_machine.c \
- draw_vs_exec.c \
- draw_vs_llvm.c \
- draw_vs_ppc.c \
- draw_vs_sse.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript
deleted file mode 100644
index 5f05aa324a..0000000000
--- a/src/gallium/auxiliary/draw/SConscript
+++ /dev/null
@@ -1,46 +0,0 @@
-Import('*')
-
-draw = env.ConvenienceLibrary(
- target = 'draw',
- source = [
- 'draw_context.c',
- 'draw_pipe.c',
- 'draw_pipe_aaline.c',
- 'draw_pipe_aapoint.c',
- 'draw_pipe_clip.c',
- 'draw_pipe_cull.c',
- 'draw_pipe_flatshade.c',
- 'draw_pipe_offset.c',
- 'draw_pipe_pstipple.c',
- 'draw_pipe_stipple.c',
- 'draw_pipe_twoside.c',
- 'draw_pipe_unfilled.c',
- 'draw_pipe_util.c',
- 'draw_pipe_validate.c',
- 'draw_pipe_vbuf.c',
- 'draw_pipe_wide_line.c',
- 'draw_pipe_wide_point.c',
- 'draw_pt.c',
- 'draw_pt_elts.c',
- 'draw_pt_emit.c',
- 'draw_pt_fetch.c',
- 'draw_pt_fetch_emit.c',
- 'draw_pt_fetch_shade_emit.c',
- 'draw_pt_fetch_shade_pipeline.c',
- 'draw_pt_post_vs.c',
- 'draw_pt_util.c',
- 'draw_pt_varray.c',
- 'draw_pt_vcache.c',
- 'draw_vertex.c',
- 'draw_vs.c',
- 'draw_vs_aos.c',
- 'draw_vs_aos_io.c',
- 'draw_vs_aos_machine.c',
- 'draw_vs_exec.c',
- 'draw_vs_llvm.c',
- 'draw_vs_ppc.c',
- 'draw_vs_sse.c',
- 'draw_vs_varient.c'
- ])
-
-auxiliaries.insert(0, draw)
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index cc5f7f0105..667aa46b20 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -36,6 +36,7 @@
#include "draw_context.h"
#include "draw_vbuf.h"
#include "draw_vs.h"
+#include "draw_gs.h"
#include "draw_pt.h"
#include "draw_pipe.h"
@@ -67,6 +68,9 @@ struct draw_context *draw_create( void )
if (!draw_vs_init( draw ))
goto fail;
+ if (!draw_gs_init( draw ))
+ goto fail;
+
return draw;
fail:
@@ -231,11 +235,19 @@ draw_set_mapped_vertex_buffer(struct draw_context *draw,
void
draw_set_mapped_constant_buffer(struct draw_context *draw,
- const void *buffer,
+ unsigned shader_type,
+ const void *buffer,
unsigned size )
{
- draw->pt.user.constants = buffer;
- draw_vs_set_constants( draw, (const float (*)[4])buffer, size );
+ debug_assert(shader_type == PIPE_SHADER_VERTEX ||
+ shader_type == PIPE_SHADER_GEOMETRY);
+ if (shader_type == PIPE_SHADER_VERTEX) {
+ draw->pt.user.vs_constants = buffer;
+ draw_vs_set_constants( draw, (const float (*)[4])buffer, size );
+ } else if (shader_type == PIPE_SHADER_GEOMETRY) {
+ draw->pt.user.gs_constants = buffer;
+ draw_gs_set_constants( draw, (const float (*)[4])buffer, size );
+ }
}
@@ -298,7 +310,7 @@ draw_set_force_passthrough( struct draw_context *draw, boolean enable )
* a post-transformed vertex.
*
* With this function, drivers that use the draw module should have no reason
- * to track the current vertex shader.
+ * to track the current vertex/geometry shader.
*
* Note that the draw module may sometimes generate vertices with extra
* attributes (such as texcoords for AA lines). The driver can call this
@@ -309,43 +321,59 @@ draw_set_force_passthrough( struct draw_context *draw, boolean enable )
* work for the drivers.
*/
int
-draw_find_vs_output(const struct draw_context *draw,
- uint semantic_name, uint semantic_index)
+draw_find_shader_output(const struct draw_context *draw,
+ uint semantic_name, uint semantic_index)
{
const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
+ const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
uint i;
- for (i = 0; i < vs->info.num_outputs; i++) {
- if (vs->info.output_semantic_name[i] == semantic_name &&
- vs->info.output_semantic_index[i] == semantic_index)
+ const struct tgsi_shader_info *info = &vs->info;
+
+ if (gs)
+ info = &gs->info;
+
+ for (i = 0; i < info->num_outputs; i++) {
+ if (info->output_semantic_name[i] == semantic_name &&
+ info->output_semantic_index[i] == semantic_index)
return i;
}
/* 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;
+ if (draw->extra_shader_outputs.semantic_name == semantic_name &&
+ draw->extra_shader_outputs.semantic_index == semantic_index) {
+ return draw->extra_shader_outputs.slot;
}
+
return 0;
}
/**
- * Return number of vertex shader outputs.
+ * Return number of the shader outputs.
+ *
+ * If geometry shader is present, its output will be returned,
+ * if not vertex shader is used.
*/
uint
-draw_num_vs_outputs(const struct draw_context *draw)
+draw_num_shader_outputs(const struct draw_context *draw)
{
uint count = draw->vs.vertex_shader->info.num_outputs;
- if (draw->extra_vp_outputs.slot > 0)
+
+ /* if geometry shader is present, its outputs go to te
+ * driver, not the vertex shaders */
+ if (draw->gs.geometry_shader)
+ count = draw->gs.geometry_shader->info.num_outputs;
+
+ if (draw->extra_shader_outputs.slot > 0)
count++;
return count;
}
/**
- * Provide TGSI sampler objects for vertex shaders that use texture fetches.
+ * Provide TGSI sampler objects for vertex/geometry shaders that use texture fetches.
* This might only be used by software drivers for the time being.
*/
void
@@ -355,6 +383,8 @@ draw_texture_samplers(struct draw_context *draw,
{
draw->vs.num_samplers = num_samplers;
draw->vs.samplers = samplers;
+ draw->gs.num_samplers = num_samplers;
+ draw->gs.samplers = samplers;
}
@@ -421,3 +451,18 @@ void draw_do_flush( struct draw_context *draw, unsigned flags )
draw->flushing = FALSE;
}
}
+
+
+int draw_current_shader_outputs(struct draw_context *draw)
+{
+ if (draw->gs.geometry_shader)
+ return draw->gs.num_gs_outputs;
+ return draw->vs.num_vs_outputs;
+}
+
+int draw_current_shader_position_output(struct draw_context *draw)
+{
+ if (draw->gs.geometry_shader)
+ return draw->gs.position_output;
+ return draw->vs.position_output;
+}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 465b8f10c6..8a64c06efc 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -45,6 +45,7 @@ struct pipe_context;
struct draw_context;
struct draw_stage;
struct draw_vertex_shader;
+struct draw_geometry_shader;
struct tgsi_sampler;
@@ -85,11 +86,11 @@ draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe
int
-draw_find_vs_output(const struct draw_context *draw,
- uint semantic_name, uint semantic_index);
+draw_find_shader_output(const struct draw_context *draw,
+ uint semantic_name, uint semantic_index);
uint
-draw_num_vs_outputs(const struct draw_context *draw);
+draw_num_shader_outputs(const struct draw_context *draw);
void
@@ -112,6 +113,17 @@ void draw_delete_vertex_shader(struct draw_context *draw,
struct draw_vertex_shader *dvs);
+/*
+ * Geometry shader functions
+ */
+struct draw_geometry_shader *
+draw_create_geometry_shader(struct draw_context *draw,
+ const struct pipe_shader_state *shader);
+void draw_bind_geometry_shader(struct draw_context *draw,
+ struct draw_geometry_shader *dvs);
+void draw_delete_geometry_shader(struct draw_context *draw,
+ struct draw_geometry_shader *dvs);
+
/*
* Vertex data functions
@@ -140,6 +152,7 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw,
unsigned attr, const void *buffer);
void draw_set_mapped_constant_buffer(struct draw_context *draw,
+ unsigned shader_type,
const void *buffer,
unsigned size );
@@ -151,6 +164,14 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw,
void draw_arrays(struct draw_context *draw, unsigned prim,
unsigned start, unsigned count);
+void
+draw_arrays_instanced(struct draw_context *draw,
+ unsigned mode,
+ unsigned start,
+ unsigned count,
+ unsigned startInstance,
+ unsigned instanceCount);
+
void draw_flush(struct draw_context *draw);
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
new file mode 100644
index 0000000000..5db2e75542
--- /dev/null
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -0,0 +1,338 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMWare Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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 "draw_gs.h"
+
+#include "draw_private.h"
+#include "draw_context.h"
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_exec.h"
+
+#include "pipe/p_shader_tokens.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#define MAX_PRIM_VERTICES 6
+/* fixme: move it from here */
+#define MAX_PRIMITIVES 64
+
+boolean
+draw_gs_init( struct draw_context *draw )
+{
+ draw->gs.machine = tgsi_exec_machine_create();
+ if (!draw->gs.machine)
+ return FALSE;
+
+ draw->gs.machine->Primitives = align_malloc(
+ MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16);
+ if (!draw->gs.machine->Primitives)
+ return FALSE;
+ memset(draw->gs.machine->Primitives, 0,
+ MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector));
+
+ return TRUE;
+}
+
+
+void draw_gs_set_constants( struct draw_context *draw,
+ const float (*constants)[4],
+ unsigned size )
+{
+}
+
+
+struct draw_geometry_shader *
+draw_create_geometry_shader(struct draw_context *draw,
+ const struct pipe_shader_state *state)
+{
+ struct draw_geometry_shader *gs;
+ int i;
+
+ gs = CALLOC_STRUCT(draw_geometry_shader);
+
+ if (!gs)
+ return NULL;
+
+ gs->state = *state;
+ gs->state.tokens = tgsi_dup_tokens(state->tokens);
+ if (!gs->state.tokens) {
+ FREE(gs);
+ return NULL;
+ }
+
+ tgsi_scan_shader(state->tokens, &gs->info);
+
+ /* setup the defaults */
+ gs->input_primitive = PIPE_PRIM_TRIANGLES;
+ gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP;
+ gs->max_output_vertices = 32;
+
+ for (i = 0; i < gs->info.num_properties; ++i) {
+ if (gs->info.properties[i].name ==
+ TGSI_PROPERTY_GS_INPUT_PRIM)
+ gs->input_primitive = gs->info.properties[i].data[0];
+ else if (gs->info.properties[i].name ==
+ TGSI_PROPERTY_GS_OUTPUT_PRIM)
+ gs->output_primitive = gs->info.properties[i].data[0];
+ else if (gs->info.properties[i].name ==
+ TGSI_PROPERTY_GS_MAX_VERTICES)
+ gs->max_output_vertices = gs->info.properties[i].data[0];
+ }
+
+ gs->machine = draw->gs.machine;
+
+ if (gs)
+ {
+ uint i;
+ for (i = 0; i < gs->info.num_outputs; i++) {
+ if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
+ gs->info.output_semantic_index[i] == 0)
+ gs->position_output = i;
+ }
+ }
+
+ return gs;
+}
+
+void draw_bind_geometry_shader(struct draw_context *draw,
+ struct draw_geometry_shader *dgs)
+{
+ draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
+
+ if (dgs) {
+ draw->gs.geometry_shader = dgs;
+ draw->gs.num_gs_outputs = dgs->info.num_outputs;
+ draw->gs.position_output = dgs->position_output;
+ draw_geometry_shader_prepare(dgs, draw);
+ }
+ else {
+ draw->gs.geometry_shader = NULL;
+ draw->gs.num_gs_outputs = 0;
+ }
+}
+
+void draw_delete_geometry_shader(struct draw_context *draw,
+ struct draw_geometry_shader *dgs)
+{
+ FREE(dgs);
+}
+
+static INLINE int num_vertices_for_prim(int prim)
+{
+ switch(prim) {
+ case PIPE_PRIM_POINTS:
+ return 1;
+ case PIPE_PRIM_LINES:
+ return 2;
+ case PIPE_PRIM_LINE_LOOP:
+ return 2;
+ case PIPE_PRIM_LINE_STRIP:
+ return 2;
+ case PIPE_PRIM_TRIANGLES:
+ return 3;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ return 3;
+ case PIPE_PRIM_TRIANGLE_FAN:
+ return 3;
+ case PIPE_PRIM_LINES_ADJACENCY:
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ return 4;
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ return 6;
+ default:
+ assert(!"Bad geometry shader input");
+ return 0;
+ }
+}
+
+static void draw_fetch_geometry_input(struct draw_geometry_shader *shader,
+ int start_primitive,
+ int num_primitives,
+ const float (*input_ptr)[4],
+ unsigned input_vertex_stride,
+ unsigned inputs_from_vs)
+{
+ struct tgsi_exec_machine *machine = shader->machine;
+ unsigned slot, vs_slot, k, j;
+ unsigned num_vertices = num_vertices_for_prim(shader->input_primitive);
+ int idx = 0;
+
+ for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; slot++) {
+ /*debug_printf("Slot = %d (semantic = %d)\n", slot,
+ shader->info.input_semantic_name[slot]);*/
+ if (shader->info.input_semantic_name[slot] ==
+ TGSI_SEMANTIC_PRIMID) {
+ for (j = 0; j < num_primitives; ++j) {
+ machine->Inputs[idx].xyzw[0].f[j] = (float)start_primitive + j;
+ machine->Inputs[idx].xyzw[1].f[j] = (float)start_primitive + j;
+ machine->Inputs[idx].xyzw[2].f[j] = (float)start_primitive + j;
+ machine->Inputs[idx].xyzw[3].f[j] = (float)start_primitive + j;
+ }
+ ++idx;
+ } else {
+ for (j = 0; j < num_primitives; ++j) {
+ int vidx = idx;
+ const float (*prim_ptr)[4];
+ /*debug_printf(" %d) Prim (num_verts = %d)\n", start_primitive + j,
+ num_vertices);*/
+ prim_ptr = (const float (*)[4])(
+ (const char *)input_ptr +
+ (j * num_vertices * input_vertex_stride));
+
+ for (k = 0; k < num_vertices; ++k, ++vidx) {
+ const float (*input)[4];
+ input = (const float (*)[4])(
+ (const char *)prim_ptr + (k * input_vertex_stride));
+ vidx = k * TGSI_EXEC_MAX_INPUT_ATTRIBS + slot;
+ /*debug_printf("\t%d)(%d) Input vert:\n", vidx, k);*/
+#if 1
+ assert(!util_is_inf_or_nan(input[vs_slot][0]));
+ assert(!util_is_inf_or_nan(input[vs_slot][1]));
+ assert(!util_is_inf_or_nan(input[vs_slot][2]));
+ assert(!util_is_inf_or_nan(input[vs_slot][3]));
+#endif
+ machine->Inputs[vidx].xyzw[0].f[j] = input[vs_slot][0];
+ machine->Inputs[vidx].xyzw[1].f[j] = input[vs_slot][1];
+ machine->Inputs[vidx].xyzw[2].f[j] = input[vs_slot][2];
+ machine->Inputs[vidx].xyzw[3].f[j] = input[vs_slot][3];
+#if 0
+ debug_printf("\t\t%d %f %f %f %f\n", slot,
+ machine->Inputs[vidx].xyzw[0].f[j],
+ machine->Inputs[vidx].xyzw[1].f[j],
+ machine->Inputs[vidx].xyzw[2].f[j],
+ machine->Inputs[vidx].xyzw[3].f[j]);
+#endif
+ }
+ }
+ ++vs_slot;
+ idx += num_vertices;
+ }
+ }
+}
+
+static INLINE void
+draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
+ int num_primitives,
+ float (*output)[4],
+ unsigned vertex_size)
+{
+ struct tgsi_exec_machine *machine = shader->machine;
+ unsigned prim_idx, j, slot;
+
+ /* Unswizzle all output results.
+ */
+ /* FIXME: handle all the primitives produced by the gs, not just
+ * the first one
+ unsigned prim_count =
+ mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];*/
+ for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) {
+ unsigned num_verts_per_prim = machine->Primitives[0];
+ for (j = 0; j < num_verts_per_prim; j++) {
+ int idx = (prim_idx * num_verts_per_prim + j) *
+ shader->info.num_outputs;
+#ifdef DEBUG_OUTPUTS
+ debug_printf("%d) Output vert:\n", idx);
+#endif
+ for (slot = 0; slot < shader->info.num_outputs; slot++) {
+ output[slot][0] = machine->Outputs[idx + slot].xyzw[0].f[prim_idx];
+ output[slot][1] = machine->Outputs[idx + slot].xyzw[1].f[prim_idx];
+ output[slot][2] = machine->Outputs[idx + slot].xyzw[2].f[prim_idx];
+ output[slot][3] = machine->Outputs[idx + slot].xyzw[3].f[prim_idx];
+#ifdef DEBUG_OUTPUTS
+ debug_printf("\t%d: %f %f %f %f\n", slot,
+ output[slot][0],
+ output[slot][1],
+ output[slot][2],
+ output[slot][3]);
+#endif
+ debug_assert(!util_is_inf_or_nan(output[slot][0]));
+ }
+ output = (float (*)[4])((char *)output + vertex_size);
+ }
+ }
+}
+
+void draw_geometry_shader_run(struct draw_geometry_shader *shader,
+ const float (*input)[4],
+ float (*output)[4],
+ const float (*constants)[4],
+ unsigned count,
+ unsigned input_stride,
+ unsigned vertex_size)
+{
+ struct tgsi_exec_machine *machine = shader->machine;
+ unsigned int i;
+ unsigned num_vertices = num_vertices_for_prim(shader->input_primitive);
+ unsigned num_primitives = count/num_vertices;
+ unsigned inputs_from_vs = 0;
+
+ machine->Consts = constants;
+
+ for (i = 0; i < shader->info.num_inputs; ++i) {
+ if (shader->info.input_semantic_name[i] != TGSI_SEMANTIC_PRIMID)
+ ++inputs_from_vs;
+ }
+
+ for (i = 0; i < num_primitives; ++i) {
+ unsigned int max_primitives = 1;
+
+ draw_fetch_geometry_input(shader, i, max_primitives, input,
+ input_stride, inputs_from_vs);
+
+ tgsi_set_exec_mask(machine,
+ 1,
+ max_primitives > 1,
+ max_primitives > 2,
+ max_primitives > 3);
+
+ /* run interpreter */
+ tgsi_exec_machine_run(machine);
+
+ draw_geometry_fetch_outputs(shader, max_primitives,
+ output, vertex_size);
+ }
+}
+
+void draw_geometry_shader_delete(struct draw_geometry_shader *shader)
+{
+ FREE((void*) shader->state.tokens);
+ FREE(shader);
+}
+
+void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
+ struct draw_context *draw)
+{
+ if (shader->machine->Tokens != shader->state.tokens) {
+ tgsi_exec_machine_bind_shader(shader->machine,
+ shader->state.tokens,
+ draw->gs.num_samplers,
+ draw->gs.samplers);
+ }
+}
diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h
new file mode 100644
index 0000000000..d6a97d9c4e
--- /dev/null
+++ b/src/gallium/auxiliary/draw/draw_gs.h
@@ -0,0 +1,76 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMWare Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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 DRAW_GS_H
+#define DRAW_GS_H
+
+#include "draw_context.h"
+#include "draw_private.h"
+
+
+#define MAX_TGSI_PRIMITIVES 4
+
+struct draw_context;
+
+/**
+ * Private version of the compiled geometry shader
+ */
+struct draw_geometry_shader {
+ struct draw_context *draw;
+
+ struct tgsi_exec_machine *machine;
+
+ /* This member will disappear shortly:*/
+ struct pipe_shader_state state;
+
+ struct tgsi_shader_info info;
+ unsigned position_output;
+
+ unsigned max_output_vertices;
+ unsigned input_primitive;
+ unsigned output_primitive;
+
+ /* Extracted from shader:
+ */
+ const float (*immediates)[4];
+};
+
+void draw_geometry_shader_run(struct draw_geometry_shader *shader,
+ const float (*input)[4],
+ float (*output)[4],
+ const float (*constants)[4],
+ unsigned count,
+ unsigned input_stride,
+ unsigned output_stride);
+
+void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
+ struct draw_context *draw);
+
+void draw_geometry_shader_delete(struct draw_geometry_shader *shader);
+
+
+#endif
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 14375426ed..4585dcdb48 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -660,13 +660,13 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
}
/* update vertex attrib info */
- aaline->tex_slot = draw->vs.num_vs_outputs;
- aaline->pos_slot = draw->vs.position_output;
+ aaline->tex_slot = draw_current_shader_outputs(draw);
+ aaline->pos_slot = draw_current_shader_position_output(draw);;
/* advertise the extra post-transformed vertex attribute */
- draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
- draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib;
- draw->extra_vp_outputs.slot = aaline->tex_slot;
+ draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+ draw->extra_shader_outputs.semantic_index = aaline->fs->generic_attrib;
+ draw->extra_shader_outputs.slot = aaline->tex_slot;
/* how many samplers? */
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
@@ -707,7 +707,7 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
aaline->state.texture);
draw->suspend_flushing = FALSE;
- draw->extra_vp_outputs.slot = 0;
+ draw->extra_shader_outputs.slot = 0;
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
index 75130a8fb0..d86717e518 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
@@ -687,14 +687,14 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
bind_aapoint_fragment_shader(aapoint);
/* update vertex attrib info */
- aapoint->tex_slot = draw->vs.num_vs_outputs;
+ aapoint->tex_slot = draw_current_shader_outputs(draw);
assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
- aapoint->pos_slot = draw->vs.position_output;
+ aapoint->pos_slot = draw_current_shader_position_output(draw);
- draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
- draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib;
- draw->extra_vp_outputs.slot = aapoint->tex_slot;
+ draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+ draw->extra_shader_outputs.semantic_index = aapoint->fs->generic_attrib;
+ draw->extra_shader_outputs.slot = aapoint->tex_slot;
/* find psize slot in post-transform vertex */
aapoint->psize_slot = -1;
@@ -731,7 +731,7 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
draw->suspend_flushing = FALSE;
- draw->extra_vp_outputs.slot = 0;
+ draw->extra_shader_outputs.slot = 0;
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index 0670268a19..51a6115ebf 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -55,7 +55,7 @@
-struct clipper {
+struct clip_stage {
struct draw_stage stage; /**< base class */
/* Basically duplicate some of the flatshading logic here:
@@ -70,9 +70,9 @@ struct clipper {
/* This is a bit confusing:
*/
-static INLINE struct clipper *clipper_stage( struct draw_stage *stage )
+static INLINE struct clip_stage *clip_stage( struct draw_stage *stage )
{
- return (struct clipper *)stage;
+ return (struct clip_stage *)stage;
}
@@ -92,11 +92,12 @@ static void interp_attr( float *fdst,
fdst[3] = LINTERP( t, fout[3], fin[3] );
}
+
static void copy_colors( struct draw_stage *stage,
struct vertex_header *dst,
const struct vertex_header *src )
{
- const struct clipper *clipper = clipper_stage(stage);
+ const struct clip_stage *clipper = clip_stage(stage);
uint i;
for (i = 0; i < clipper->num_color_attribs; i++) {
const uint attr = clipper->color_attribs[i];
@@ -108,14 +109,14 @@ static void copy_colors( struct draw_stage *stage,
/* Interpolate between two vertices to produce a third.
*/
-static void interp( const struct clipper *clip,
+static void interp( const struct clip_stage *clip,
struct vertex_header *dst,
float t,
const struct vertex_header *out,
const struct vertex_header *in )
{
- const unsigned nr_attrs = clip->stage.draw->vs.num_vs_outputs;
- const unsigned pos_attr = clip->stage.draw->vs.position_output;
+ const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
+ const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
unsigned j;
/* Vertex header.
@@ -179,7 +180,7 @@ static void emit_poly( struct draw_stage *stage,
header.v[2] = inlist[0]; /* keep in v[2] for flatshading */
if (i == n-1)
- header.flags |= edge_last;
+ header.flags |= edge_last;
if (0) {
const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
@@ -200,13 +201,14 @@ static void emit_poly( struct draw_stage *stage,
}
}
+
static INLINE float
dot4(const float *a, const float *b)
{
- return (a[0]*b[0] +
- a[1]*b[1] +
- a[2]*b[2] +
- a[3]*b[3]);
+ return (a[0] * b[0] +
+ a[1] * b[1] +
+ a[2] * b[2] +
+ a[3] * b[3]);
}
@@ -217,7 +219,7 @@ do_clip_tri( struct draw_stage *stage,
struct prim_header *header,
unsigned clipmask )
{
- struct clipper *clipper = clipper_stage( stage );
+ struct clip_stage *clipper = clip_stage( stage );
struct vertex_header *a[MAX_CLIPPED_VERTICES];
struct vertex_header *b[MAX_CLIPPED_VERTICES];
struct vertex_header **inlist = a;
@@ -280,6 +282,7 @@ do_clip_tri( struct draw_stage *stage,
dp_prev = dp;
}
+ /* swap in/out lists */
{
struct vertex_header **tmp = inlist;
inlist = outlist;
@@ -291,15 +294,11 @@ do_clip_tri( struct draw_stage *stage,
/* If flat-shading, copy color to new provoking vertex.
*/
if (clipper->flat && inlist[0] != header->v[2]) {
- if (1) {
- inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
- }
+ inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
copy_colors(stage, inlist[0], header->v[2]);
}
-
-
/* Emit the polygon as triangles to the setup stage:
*/
if (n >= 3)
@@ -314,7 +313,7 @@ do_clip_line( struct draw_stage *stage,
struct prim_header *header,
unsigned clipmask )
{
- const struct clipper *clipper = clipper_stage( stage );
+ const struct clip_stage *clipper = clip_stage( stage );
struct vertex_header *v0 = header->v[0];
struct vertex_header *v1 = header->v[1];
const float *pos0 = v0->clip;
@@ -416,13 +415,14 @@ clip_tri( struct draw_stage *stage,
}
}
+
/* Update state. Could further delay this until we hit the first
* primitive that really requires clipping.
*/
static void
clip_init_state( struct draw_stage *stage )
{
- struct clipper *clipper = clipper_stage( stage );
+ struct clip_stage *clipper = clip_stage( stage );
clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE;
@@ -488,7 +488,7 @@ static void clip_destroy( struct draw_stage *stage )
*/
struct draw_stage *draw_clip_stage( struct draw_context *draw )
{
- struct clipper *clipper = CALLOC_STRUCT(clipper);
+ struct clip_stage *clipper = CALLOC_STRUCT(clip_stage);
if (clipper == NULL)
goto fail;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c
index 0a70483858..11b39db599 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_cull.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c
@@ -55,7 +55,7 @@ static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
static void cull_tri( struct draw_stage *stage,
struct prim_header *header )
{
- const unsigned pos = stage->draw->vs.position_output;
+ const unsigned pos = draw_current_shader_position_output(stage->draw);
/* Window coords: */
const float *v0 = header->v[0]->data[pos];
diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c
index 40798a5d6e..e829492423 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_offset.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c
@@ -63,7 +63,7 @@ static INLINE struct offset_stage *offset_stage( struct draw_stage *stage )
static void do_offset_tri( struct draw_stage *stage,
struct prim_header *header )
{
- const unsigned pos = stage->draw->vs.position_output;
+ const unsigned pos = draw_current_shader_position_output(stage->draw);
struct offset_stage *offset = offset_stage(stage);
float inv_det = 1.0f / header->det;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
index 6e921bac27..70fbab9ea7 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
@@ -73,7 +73,8 @@ screen_interp( struct draw_context *draw,
const struct vertex_header *v1 )
{
uint attr;
- for (attr = 0; attr < draw->vs.num_vs_outputs; attr++) {
+ int num_outputs = draw_current_shader_outputs(draw);
+ for (attr = 0; attr < num_outputs; attr++) {
const float *val0 = v0->data[attr];
const float *val1 = v1->data[attr];
float *newv = dst->data[attr];
@@ -121,7 +122,7 @@ stipple_line(struct draw_stage *stage, struct prim_header *header)
struct stipple_stage *stipple = stipple_stage(stage);
struct vertex_header *v0 = header->v[0];
struct vertex_header *v1 = header->v[1];
- const unsigned pos = stage->draw->vs.position_output;
+ const unsigned pos = draw_current_shader_position_output(stage->draw);
const float *pos0 = v0->data[pos];
const float *pos1 = v1->data[pos];
float start = 0;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
index 1a5269c0de..d40c035240 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
@@ -138,7 +138,7 @@ emit_vertex( struct vbuf_stage *vbuf,
/* Note: we really do want data[0] here, not data[pos]:
*/
vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0);
- vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr);
+ vbuf->translate->run(vbuf->translate, 0, 1, 0, vbuf->vertex_ptr);
if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr);
@@ -271,10 +271,12 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim )
emit_sz = 0;
break;
}
-
+
+ hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
hw_key.element[i].input_buffer = src_buffer;
hw_key.element[i].input_offset = src_offset;
+ hw_key.element[i].instance_divisor = 0;
hw_key.element[i].output_format = output_format;
hw_key.element[i].output_offset = dst_offset;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
index f32cbef983..3073c87082 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
@@ -59,7 +59,7 @@ static void wideline_line( struct draw_stage *stage,
struct prim_header *header )
{
/*const struct wideline_stage *wide = wideline_stage(stage);*/
- const unsigned pos = stage->draw->vs.position_output;
+ const unsigned pos = draw_current_shader_position_output(stage->draw);
const float half_width = 0.5f * stage->draw->rasterizer->line_width;
struct prim_header tri;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index 7d76a7dbf3..8dc50c0ab4 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -112,7 +112,7 @@ static void set_texcoords(const struct widepoint_stage *wide,
if (wide->point_coord_fs_input >= 0) {
/* put gl_PointCoord into the extra vertex slot */
- uint slot = wide->stage.draw->extra_vp_outputs.slot;
+ uint slot = wide->stage.draw->extra_shader_outputs.slot;
v->data[slot][0] = tc[0];
v->data[slot][1] = tc[1];
v->data[slot][2] = 0.0F;
@@ -130,7 +130,7 @@ static void widepoint_point( struct draw_stage *stage,
struct prim_header *header )
{
const struct widepoint_stage *wide = widepoint_stage(stage);
- const unsigned pos = stage->draw->vs.position_output;
+ const unsigned pos = draw_current_shader_position_output(stage->draw);
const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite;
float half_size;
float left_adj, right_adj, bot_adj, top_adj;
@@ -257,13 +257,13 @@ static void widepoint_first_point( struct draw_stage *stage,
wide->point_coord_fs_input = find_pntc_input_attrib(draw);
/* setup extra vp output (point coord implemented as a texcoord) */
- draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
- draw->extra_vp_outputs.semantic_index = 0;
- draw->extra_vp_outputs.slot = draw->vs.num_vs_outputs;
+ draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+ draw->extra_shader_outputs.semantic_index = 0;
+ draw->extra_shader_outputs.slot = draw_current_shader_outputs(draw);
}
else {
wide->point_coord_fs_input = -1;
- draw->extra_vp_outputs.slot = 0;
+ draw->extra_shader_outputs.slot = 0;
}
wide->psize_slot = -1;
@@ -287,7 +287,7 @@ static void widepoint_flush( struct draw_stage *stage, unsigned flags )
{
stage->point = widepoint_first_point;
stage->next->flush( stage->next, flags );
- stage->draw->extra_vp_outputs.slot = 0;
+ stage->draw->extra_shader_outputs.slot = 0;
}
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 3850cede1e..d5e1c0ce2a 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -152,8 +152,9 @@ struct draw_context
/** vertex arrays */
const void *vbuffer[PIPE_MAX_ATTRIBS];
- /** constant buffer (for vertex shader) */
- const void *constants;
+ /** constant buffer (for vertex/geometry shader) */
+ const void *vs_constants;
+ const void *gs_constants;
} user;
boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */
@@ -171,6 +172,8 @@ struct draw_context
boolean force_passthrough; /**< never clip or shade */
+ boolean dump_vs;
+
double mrd; /**< minimum resolvable depth value, for polygon offset */
/* pipe state that we need: */
@@ -211,6 +214,18 @@ struct draw_context
struct translate_cache *emit_cache;
} vs;
+ struct {
+ struct draw_geometry_shader *geometry_shader;
+ uint num_gs_outputs; /**< convenience, from geometry_shader */
+ uint position_output;
+
+ /** TGSI program interpreter runtime state */
+ struct tgsi_exec_machine *machine;
+
+ uint num_samplers;
+ struct tgsi_sampler **samplers;
+ } gs;
+
/* Clip derived state:
*/
float plane[12][4];
@@ -222,10 +237,12 @@ struct draw_context
uint semantic_name;
uint semantic_index;
int slot;
- } extra_vp_outputs;
+ } extra_shader_outputs;
unsigned reduced_prim;
+ unsigned instance_id;
+
void *driver_private;
};
@@ -245,6 +262,19 @@ void draw_vs_set_constants( struct draw_context *,
+/*******************************************************************************
+ * Geometry shading code:
+ */
+boolean draw_gs_init( struct draw_context *draw );
+void draw_gs_set_constants( struct draw_context *,
+ const float (*constants)[4],
+ unsigned size );
+
+/*******************************************************************************
+ * Common shading code:
+ */
+int draw_current_shader_outputs(struct draw_context *draw);
+int draw_current_shader_position_output(struct draw_context *draw);
/*******************************************************************************
* Vertex processing (was passthrough) code:
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 2801dbafe4..a5ddec5286 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -280,20 +280,33 @@ void
draw_arrays(struct draw_context *draw, unsigned prim,
unsigned start, unsigned count)
{
- unsigned reduced_prim = u_reduced_prim(prim);
+ draw_arrays_instanced(draw, prim, start, count, 0, 1);
+}
+
+void
+draw_arrays_instanced(struct draw_context *draw,
+ unsigned mode,
+ unsigned start,
+ unsigned count,
+ unsigned startInstance,
+ unsigned instanceCount)
+{
+ unsigned reduced_prim = u_reduced_prim(mode);
+ unsigned instance;
+
if (reduced_prim != draw->reduced_prim) {
- draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+ draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
draw->reduced_prim = reduced_prim;
}
if (0)
- draw_print_arrays(draw, prim, start, MIN2(count, 20));
+ draw_print_arrays(draw, mode, start, MIN2(count, 20));
#if 0
{
int i;
- debug_printf("draw_arrays(prim=%u start=%u count=%u):\n",
- prim, start, count);
+ debug_printf("draw_arrays(mode=%u start=%u count=%u):\n",
+ mode, start, count);
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
debug_printf("Elements:\n");
for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
@@ -311,6 +324,8 @@ draw_arrays(struct draw_context *draw, unsigned prim,
}
#endif
- /* drawing done here: */
- draw_pt_arrays(draw, prim, start, count);
+ for (instance = 0; instance < instanceCount; instance++) {
+ draw->instance_id = instance + startInstance;
+ draw_pt_arrays(draw, mode, start, count);
+ }
}
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 20edf7a227..d5e0d92a60 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -183,7 +183,8 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw );
struct pt_fetch;
void draw_pt_fetch_prepare( struct pt_fetch *fetch,
unsigned vertex_input_count,
- unsigned vertex_size );
+ unsigned vertex_size,
+ unsigned instance_id_index );
void draw_pt_fetch_run( struct pt_fetch *fetch,
const unsigned *elts,
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
index 064e16c295..4fb53276bb 100644
--- a/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -121,10 +121,12 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
emit_sz = 0;
break;
}
-
+
+ hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
hw_key.element[i].input_buffer = src_buffer;
hw_key.element[i].input_offset = src_offset;
+ hw_key.element[i].instance_divisor = 0;
hw_key.element[i].output_format = output_format;
hw_key.element[i].output_offset = dst_offset;
@@ -204,6 +206,7 @@ void draw_pt_emit( struct pt_emit *emit,
translate->run( translate,
0,
vertex_count,
+ draw->instance_id,
hw_verts );
render->unmap_vertices( render,
@@ -263,6 +266,7 @@ void draw_pt_emit_linear(struct pt_emit *emit,
translate->run(translate,
0,
count,
+ draw->instance_id,
hw_verts);
if (0) {
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 305bfef435..55e7a7b81a 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -58,12 +58,14 @@ struct pt_fetch {
*/
void draw_pt_fetch_prepare( struct pt_fetch *fetch,
unsigned vs_input_count,
- unsigned vertex_size )
+ unsigned vertex_size,
+ unsigned instance_id_index )
{
struct draw_context *draw = fetch->draw;
unsigned nr_inputs;
- unsigned i, nr = 0;
+ unsigned i, nr = 0, ei = 0;
unsigned dst_offset = 0;
+ unsigned num_extra_inputs = 0;
struct translate_key key;
fetch->vertex_size = vertex_size;
@@ -78,9 +80,11 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
{
/* Need to set header->vertex_id = 0xffff somehow.
*/
+ key.element[nr].type = TRANSLATE_ELEMENT_NORMAL;
key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT;
key.element[nr].input_buffer = draw->pt.nr_vertex_buffers;
key.element[nr].input_offset = 0;
+ key.element[nr].instance_divisor = 0;
key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT;
key.element[nr].output_offset = dst_offset;
dst_offset += 1 * sizeof(float);
@@ -91,19 +95,36 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
*/
dst_offset += 4 * sizeof(float);
}
-
- assert( draw->pt.nr_vertex_elements >= vs_input_count );
- nr_inputs = MIN2( vs_input_count, draw->pt.nr_vertex_elements );
+ if (instance_id_index != ~0) {
+ num_extra_inputs++;
+ }
+
+ assert(draw->pt.nr_vertex_elements + num_extra_inputs >= vs_input_count);
+
+ nr_inputs = MIN2(vs_input_count, draw->pt.nr_vertex_elements + num_extra_inputs);
for (i = 0; i < nr_inputs; i++) {
- key.element[nr].input_format = draw->pt.vertex_element[i].src_format;
- key.element[nr].input_buffer = draw->pt.vertex_element[i].vertex_buffer_index;
- key.element[nr].input_offset = draw->pt.vertex_element[i].src_offset;
- key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- key.element[nr].output_offset = dst_offset;
+ if (i == instance_id_index) {
+ key.element[nr].type = TRANSLATE_ELEMENT_INSTANCE_ID;
+ key.element[nr].input_format = PIPE_FORMAT_R32_USCALED;
+ key.element[nr].output_format = PIPE_FORMAT_R32_USCALED;
+ key.element[nr].output_offset = dst_offset;
+
+ dst_offset += sizeof(uint);
+ } else {
+ key.element[nr].type = TRANSLATE_ELEMENT_NORMAL;
+ key.element[nr].input_format = draw->pt.vertex_element[ei].src_format;
+ key.element[nr].input_buffer = draw->pt.vertex_element[ei].vertex_buffer_index;
+ key.element[nr].input_offset = draw->pt.vertex_element[ei].src_offset;
+ key.element[nr].instance_divisor = draw->pt.vertex_element[ei].instance_divisor;
+ key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ key.element[nr].output_offset = dst_offset;
+
+ ei++;
+ dst_offset += 4 * sizeof(float);
+ }
- dst_offset += 4 * sizeof(float);
nr++;
}
@@ -158,6 +179,7 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
translate->run_elts( translate,
elts,
count,
+ draw->instance_id,
verts );
}
@@ -183,6 +205,7 @@ void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
translate->run( translate,
start,
count,
+ draw->instance_id,
verts );
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index e7fe6b3b76..2a604470e9 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -166,9 +166,11 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
continue;
}
+ key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
key.element[i].input_format = input_format;
key.element[i].input_buffer = input_buffer;
key.element[i].input_offset = input_offset;
+ key.element[i].instance_divisor = src->instance_divisor;
key.element[i].output_format = output_format;
key.element[i].output_offset = dst_offset;
@@ -256,6 +258,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
feme->translate->run_elts( feme->translate,
fetch_elts,
fetch_count,
+ draw->instance_id,
hw_verts );
if (0) {
@@ -314,6 +317,7 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
feme->translate->run( feme->translate,
start,
count,
+ draw->instance_id,
hw_verts );
if (0) {
@@ -374,6 +378,7 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,
feme->translate->run( feme->translate,
start,
count,
+ draw->instance_id,
hw_verts );
draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) );
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index 932113783d..279f4eec63 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -32,6 +32,7 @@
#include "draw/draw_vertex.h"
#include "draw/draw_pt.h"
#include "draw/draw_vs.h"
+#include "draw/draw_gs.h"
#include "translate/translate.h"
@@ -58,6 +59,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *vs = draw->vs.vertex_shader;
+ unsigned i;
+ boolean instance_id_index = ~0;
/* Add one to num_outputs because the pipeline occasionally tags on
* an additional texcoord, eg for AA lines.
@@ -65,6 +68,15 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
unsigned nr = MAX2( vs->info.num_inputs,
vs->info.num_outputs + 1 );
+ /* Scan for instanceID system value.
+ */
+ for (i = 0; i < vs->info.num_inputs; i++) {
+ if (vs->info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) {
+ instance_id_index = i;
+ break;
+ }
+ }
+
fpme->prim = prim;
fpme->opt = opt;
@@ -78,7 +90,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
draw_pt_fetch_prepare( fpme->fetch,
vs->info.num_inputs,
- fpme->vertex_size );
+ fpme->vertex_size,
+ instance_id_index );
/* XXX: it's not really gl rasterization rules we care about here,
* but gl vs dx9 clip spaces.
*/
@@ -119,7 +132,8 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
{
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
- struct draw_vertex_shader *shader = draw->vs.vertex_shader;
+ struct draw_vertex_shader *vshader = draw->vs.vertex_shader;
+ struct draw_geometry_shader *gshader = draw->gs.geometry_shader;
unsigned opt = fpme->opt;
unsigned alloc_count = align( fetch_count, 4 );
@@ -147,13 +161,21 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
*/
if (opt & PT_SHADE)
{
- shader->run_linear(shader,
- (const float (*)[4])pipeline_verts->data,
- ( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.constants,
- fetch_count,
- fpme->vertex_size,
- fpme->vertex_size);
+ vshader->run_linear(vshader,
+ (const float (*)[4])pipeline_verts->data,
+ ( float (*)[4])pipeline_verts->data,
+ (const float (*)[4])draw->pt.user.vs_constants,
+ fetch_count,
+ fpme->vertex_size,
+ fpme->vertex_size);
+ if (gshader)
+ draw_geometry_shader_run(gshader,
+ (const float (*)[4])pipeline_verts->data,
+ ( float (*)[4])pipeline_verts->data,
+ (const float (*)[4])draw->pt.user.gs_constants,
+ fetch_count,
+ fpme->vertex_size,
+ fpme->vertex_size);
}
if (draw_pt_post_vs_run( fpme->post_vs,
@@ -196,6 +218,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *shader = draw->vs.vertex_shader;
+ struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
unsigned opt = fpme->opt;
unsigned alloc_count = align( count, 4 );
@@ -226,10 +249,19 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.constants,
+ (const float (*)[4])draw->pt.user.vs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
+
+ if (geometry_shader)
+ draw_geometry_shader_run(geometry_shader,
+ (const float (*)[4])pipeline_verts->data,
+ ( float (*)[4])pipeline_verts->data,
+ (const float (*)[4])draw->pt.user.gs_constants,
+ count,
+ fpme->vertex_size,
+ fpme->vertex_size);
}
if (draw_pt_post_vs_run( fpme->post_vs,
@@ -270,6 +302,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *shader = draw->vs.vertex_shader;
+ struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
unsigned opt = fpme->opt;
unsigned alloc_count = align( count, 4 );
@@ -296,10 +329,19 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.constants,
+ (const float (*)[4])draw->pt.user.vs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
+
+ if (geometry_shader)
+ draw_geometry_shader_run(geometry_shader,
+ (const float (*)[4])pipeline_verts->data,
+ ( float (*)[4])pipeline_verts->data,
+ (const float (*)[4])draw->pt.user.gs_constants,
+ count,
+ fpme->vertex_size,
+ fpme->vertex_size);
}
if (draw_pt_post_vs_run( fpme->post_vs,
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 9dfb47837e..55151823a1 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -100,7 +100,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
struct vertex_header *out = vertices;
const float *scale = pvs->draw->viewport.scale;
const float *trans = pvs->draw->viewport.translate;
- const unsigned pos = pvs->draw->vs.position_output;
+ const unsigned pos = draw_current_shader_position_output(pvs->draw);
unsigned clipped = 0;
unsigned j;
@@ -190,7 +190,7 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs,
struct vertex_header *out = vertices;
const float *scale = pvs->draw->viewport.scale;
const float *trans = pvs->draw->viewport.translate;
- const unsigned pos = pvs->draw->vs.position_output;
+ const unsigned pos = draw_current_shader_position_output(pvs->draw);
unsigned j;
if (0) debug_printf("%s\n", __FUNCTION__);
diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c
index b61fa29143..17c3b8cec2 100644
--- a/src/gallium/auxiliary/draw/draw_pt_util.c
+++ b/src/gallium/auxiliary/draw/draw_pt_util.c
@@ -50,16 +50,32 @@ void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr)
*first = 2;
*incr = 1;
break;
+ case PIPE_PRIM_LINES_ADJACENCY:
+ *first = 4;
+ *incr = 2;
+ break;
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ *first = 4;
+ *incr = 1;
+ break;
case PIPE_PRIM_TRIANGLES:
*first = 3;
*incr = 3;
break;
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ *first = 6;
+ *incr = 3;
+ break;
case PIPE_PRIM_TRIANGLE_STRIP:
case PIPE_PRIM_TRIANGLE_FAN:
case PIPE_PRIM_POLYGON:
*first = 3;
*incr = 1;
break;
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ *first = 6;
+ *incr = 1;
+ break;
case PIPE_PRIM_QUADS:
*first = 4;
*incr = 4;
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
index 010c7a18a7..f0aec5feba 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
+++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
@@ -36,6 +36,10 @@ static void FUNC(struct draw_pt_front_end *frontend,
case PIPE_PRIM_TRIANGLE_STRIP:
case PIPE_PRIM_QUADS:
case PIPE_PRIM_QUAD_STRIP:
+ case PIPE_PRIM_LINES_ADJACENCY:
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
for (j = 0; j < count;) {
unsigned remaining = count - j;
unsigned nr = trim( MIN2(varray->driver_fetch_max, remaining), first, incr );
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index 3553689532..60b4dd9704 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -83,6 +83,10 @@ draw_create_vertex_shader(struct draw_context *draw,
{
struct draw_vertex_shader *vs;
+ if (draw->dump_vs) {
+ tgsi_dump(shader->tokens, 0);
+ }
+
vs = draw_create_vs_llvm( draw, shader );
if (!vs) {
vs = draw_create_vs_sse( draw, shader );
@@ -152,6 +156,8 @@ draw_delete_vertex_shader(struct draw_context *draw,
boolean
draw_vs_init( struct draw_context *draw )
{
+ draw->dump_vs = debug_get_bool_option("GALLIUM_DUMP_VS", FALSE);
+
draw->vs.machine = tgsi_exec_machine_create();
if (!draw->vs.machine)
return FALSE;
diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h
index e3b807ebd0..00036cfe68 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -43,6 +43,7 @@ struct draw_varient_input
enum pipe_format format;
unsigned buffer;
unsigned offset;
+ unsigned instance_divisor;
};
struct draw_varient_output
diff --git a/src/gallium/auxiliary/draw/draw_vs_ppc.c b/src/gallium/auxiliary/draw/draw_vs_ppc.c
index ad184bd696..da9f3e3d35 100644
--- a/src/gallium/auxiliary/draw/draw_vs_ppc.c
+++ b/src/gallium/auxiliary/draw/draw_vs_ppc.c
@@ -98,9 +98,9 @@ vs_ppc_run_linear( struct draw_vertex_shader *base,
/* loop over verts */
for (i = 0; i < count; i += MAX_VERTICES) {
const uint max_vertices = MIN2(MAX_VERTICES, count - i);
- float inputs_soa[PIPE_MAX_SHADER_INPUTS][4][4] ALIGN16_ATTRIB;
- float outputs_soa[PIPE_MAX_SHADER_OUTPUTS][4][4] ALIGN16_ATTRIB;
- float temps_soa[TGSI_EXEC_NUM_TEMPS][4][4] ALIGN16_ATTRIB;
+ PIPE_ALIGN_VAR(16) float inputs_soa[PIPE_MAX_SHADER_INPUTS][4][4];
+ PIPE_ALIGN_VAR(16) float outputs_soa[PIPE_MAX_SHADER_OUTPUTS][4][4];
+ PIPE_ALIGN_VAR(16) float temps_soa[TGSI_EXEC_NUM_TEMPS][4][4];
uint attr;
/* convert (up to) four input verts to SoA format */
diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c
index 7ee567d478..9f40030f39 100644
--- a/src/gallium/auxiliary/draw/draw_vs_varient.c
+++ b/src/gallium/auxiliary/draw/draw_vs_varient.c
@@ -142,16 +142,18 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient,
vsvg->fetch->run_elts( vsvg->fetch,
elts,
count,
+ vsvg->draw->instance_id,
temp_buffer );
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
- (const float (*)[4])vsvg->base.vs->draw->pt.user.constants,
+ (const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants,
count,
temp_vertex_stride,
temp_vertex_stride);
+ /* FIXME: geometry shading? */
if (vsvg->base.key.clip) {
/* not really handling clipping, just do the rhw so we can
@@ -180,6 +182,7 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient,
vsvg->emit->run( vsvg->emit,
0, count,
+ vsvg->draw->instance_id,
output_buffer );
FREE(temp_buffer);
@@ -202,12 +205,13 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient,
vsvg->fetch->run( vsvg->fetch,
start,
count,
+ vsvg->draw->instance_id,
temp_buffer );
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
- (const float (*)[4])vsvg->base.vs->draw->pt.user.constants,
+ (const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants,
count,
temp_vertex_stride,
temp_vertex_stride);
@@ -238,6 +242,7 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient,
vsvg->emit->run( vsvg->emit,
0, count,
+ vsvg->draw->instance_id,
output_buffer );
FREE(temp_buffer);
@@ -280,9 +285,11 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs,
fetch.nr_elements = key->nr_inputs;
fetch.output_stride = vsvg->temp_vertex_stride;
for (i = 0; i < key->nr_inputs; i++) {
+ fetch.element[i].type = TRANSLATE_ELEMENT_NORMAL;
fetch.element[i].input_format = key->element[i].in.format;
fetch.element[i].input_buffer = key->element[i].in.buffer;
fetch.element[i].input_offset = key->element[i].in.offset;
+ fetch.element[i].instance_divisor = 0;
fetch.element[i].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
fetch.element[i].output_offset = i * 4 * sizeof(float);
assert(fetch.element[i].output_offset < fetch.output_stride);
@@ -294,17 +301,21 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs,
for (i = 0; i < key->nr_outputs; i++) {
if (key->element[i].out.format != EMIT_1F_PSIZE)
{
+ emit.element[i].type = TRANSLATE_ELEMENT_NORMAL;
emit.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
emit.element[i].input_buffer = 0;
emit.element[i].input_offset = key->element[i].out.vs_output * 4 * sizeof(float);
+ emit.element[i].instance_divisor = 0;
emit.element[i].output_format = draw_translate_vinfo_format(key->element[i].out.format);
emit.element[i].output_offset = key->element[i].out.offset;
assert(emit.element[i].input_offset <= fetch.output_stride);
}
else {
+ emit.element[i].type = TRANSLATE_ELEMENT_NORMAL;
emit.element[i].input_format = PIPE_FORMAT_R32_FLOAT;
emit.element[i].input_buffer = 1;
emit.element[i].input_offset = 0;
+ emit.element[i].instance_divisor = 0;
emit.element[i].output_format = PIPE_FORMAT_R32_FLOAT;
emit.element[i].output_offset = key->element[i].out.offset;
}
diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile
deleted file mode 100644
index 5a96d94ec3..0000000000
--- a/src/gallium/auxiliary/gallivm/Makefile
+++ /dev/null
@@ -1,92 +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 gallivmsoabuiltins.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 > temp1.bin
- (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
- rm temp1.bin
-
-gallivmsoabuiltins.cpp: soabuiltins.c
- clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin
- (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
- rm temp2.bin
-
-# 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
- -rm -f gallivmsoabuiltins.cpp
-
-symlinks:
-
-
-include depend
diff --git a/src/gallium/auxiliary/gallivm/SConscript b/src/gallium/auxiliary/gallivm/SConscript
deleted file mode 100644
index c0aa51b90a..0000000000
--- a/src/gallium/auxiliary/gallivm/SConscript
+++ /dev/null
@@ -1,16 +0,0 @@
-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)
diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
index 5cafe8c3f0..8f7d3b7100 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -552,7 +552,7 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_SHL:
break;
- case TGSI_OPCODE_SHR:
+ case TGSI_OPCODE_ISHR:
break;
case TGSI_OPCODE_AND:
break;
@@ -919,7 +919,7 @@ translate_instructionir(llvm::Module *module,
break;
case TGSI_OPCODE_SHL:
break;
- case TGSI_OPCODE_SHR:
+ case TGSI_OPCODE_ISHR:
break;
case TGSI_OPCODE_AND:
break;
diff --git a/src/gallium/auxiliary/indices/Makefile b/src/gallium/auxiliary/indices/Makefile
deleted file mode 100644
index f2ebc3f410..0000000000
--- a/src/gallium/auxiliary/indices/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = indices
-
-C_SOURCES = \
- u_indices_gen.c \
- u_unfilled_gen.c
-
-include ../../Makefile.template
-
-u_indices_gen.c: u_indices_gen.py
- python $< > $@
-
-u_unfilled_gen.c: u_unfilled_gen.py
- python $< > $@
diff --git a/src/gallium/auxiliary/indices/SConscript b/src/gallium/auxiliary/indices/SConscript
deleted file mode 100644
index 712e215534..0000000000
--- a/src/gallium/auxiliary/indices/SConscript
+++ /dev/null
@@ -1,28 +0,0 @@
-Import('*')
-
-from sys import executable as python_cmd
-
-env.CodeGenerate(
- target = 'u_indices_gen.c',
- script = 'u_indices_gen.py',
- source = [],
- command = python_cmd + ' $SCRIPT > $TARGET'
-)
-
-env.CodeGenerate(
- target = 'u_unfilled_gen.c',
- script = 'u_unfilled_gen.py',
- source = [],
- command = python_cmd + ' $SCRIPT > $TARGET'
-)
-
-indices = env.ConvenienceLibrary(
- target = 'indices',
- source = [
-# 'u_indices.c',
-# 'u_unfilled_indices.c',
- 'u_indices_gen.c',
- 'u_unfilled_gen.c',
- ])
-
-auxiliaries.insert(0, indices)
diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile
deleted file mode 100644
index 1c00ba8d98..0000000000
--- a/src/gallium/auxiliary/pipebuffer/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = pipebuffer
-
-C_SOURCES = \
- pb_buffer_fenced.c \
- pb_buffer_malloc.c \
- pb_bufmgr_alt.c \
- pb_bufmgr_cache.c \
- pb_bufmgr_debug.c \
- pb_bufmgr_fenced.c \
- pb_bufmgr_mm.c \
- pb_bufmgr_ondemand.c \
- pb_bufmgr_pool.c \
- pb_bufmgr_slab.c \
- pb_validate.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript
deleted file mode 100644
index 8e9f06abe4..0000000000
--- a/src/gallium/auxiliary/pipebuffer/SConscript
+++ /dev/null
@@ -1,19 +0,0 @@
-Import('*')
-
-pipebuffer = env.ConvenienceLibrary(
- target = 'pipebuffer',
- source = [
- 'pb_buffer_fenced.c',
- 'pb_buffer_malloc.c',
- 'pb_bufmgr_alt.c',
- 'pb_bufmgr_cache.c',
- 'pb_bufmgr_debug.c',
- 'pb_bufmgr_fenced.c',
- 'pb_bufmgr_mm.c',
- 'pb_bufmgr_ondemand.c',
- 'pb_bufmgr_pool.c',
- 'pb_bufmgr_slab.c',
- 'pb_validate.c',
- ])
-
-auxiliaries.insert(0, pipebuffer)
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index a9375abd21..a4b78f1494 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -80,27 +80,11 @@ struct fenced_buffer_list
*/
struct fenced_buffer
{
- /*
- * Immutable members.
- */
-
struct pb_buffer base;
+
struct pb_buffer *buffer;
- struct fenced_buffer_list *list;
-
- /**
- * Protected by fenced_buffer_list::mutex
- */
- struct list_head head;
- /**
- * Following members are mutable and protected by this mutex.
- *
- * You may lock this mutex alone, or lock it with fenced_buffer_list::mutex
- * held, but in order to prevent deadlocks you must never lock
- * fenced_buffer_list::mutex with this mutex held.
- */
- pipe_mutex mutex;
+ /* FIXME: protect access with mutex */
/**
* A bitmask of PIPE_BUFFER_USAGE_CPU/GPU_READ/WRITE describing the current
@@ -112,6 +96,9 @@ struct fenced_buffer
struct pb_validate *vl;
unsigned validation_flags;
struct pipe_fence_handle *fence;
+
+ struct list_head head;
+ struct fenced_buffer_list *list;
};
@@ -123,24 +110,15 @@ fenced_buffer(struct pb_buffer *buf)
}
-/**
- * Add the buffer to the fenced list.
- *
- * fenced_buffer_list::mutex and fenced_buffer::mutex must be held, in this
- * order before calling this function.
- *
- * Reference count should be incremented before calling this function.
- */
static INLINE void
-fenced_buffer_add_locked(struct fenced_buffer_list *fenced_list,
- struct fenced_buffer *fenced_buf)
+_fenced_buffer_add(struct fenced_buffer *fenced_buf)
{
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
+
assert(pipe_is_referenced(&fenced_buf->base.base.reference));
assert(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE);
assert(fenced_buf->fence);
- /* TODO: Move the reference count increment here */
-
#ifdef DEBUG
LIST_DEL(&fenced_buf->head);
assert(fenced_list->numUnfenced);
@@ -152,16 +130,32 @@ fenced_buffer_add_locked(struct fenced_buffer_list *fenced_list,
/**
- * Remove the buffer from the fenced list.
- *
- * fenced_buffer_list::mutex and fenced_buffer::mutex must be held, in this
- * order before calling this function.
- *
- * Reference count should be decremented after calling this function.
+ * Actually destroy the buffer.
*/
static INLINE void
-fenced_buffer_remove_locked(struct fenced_buffer_list *fenced_list,
- struct fenced_buffer *fenced_buf)
+_fenced_buffer_destroy(struct fenced_buffer *fenced_buf)
+{
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
+
+ assert(!pipe_is_referenced(&fenced_buf->base.base.reference));
+ assert(!fenced_buf->fence);
+#ifdef DEBUG
+ assert(fenced_buf->head.prev);
+ assert(fenced_buf->head.next);
+ LIST_DEL(&fenced_buf->head);
+ assert(fenced_list->numUnfenced);
+ --fenced_list->numUnfenced;
+#else
+ (void)fenced_list;
+#endif
+ pb_reference(&fenced_buf->buffer, NULL);
+ FREE(fenced_buf);
+}
+
+
+static INLINE void
+_fenced_buffer_remove(struct fenced_buffer_list *fenced_list,
+ struct fenced_buffer *fenced_buf)
{
struct pb_fence_ops *ops = fenced_list->ops;
@@ -183,53 +177,37 @@ fenced_buffer_remove_locked(struct fenced_buffer_list *fenced_list,
++fenced_list->numUnfenced;
#endif
- /* TODO: Move the reference count decrement and destruction here */
+ /**
+ * FIXME!!!
+ */
+
+ if(!pipe_is_referenced(&fenced_buf->base.base.reference))
+ _fenced_buffer_destroy(fenced_buf);
}
-/**
- * Wait for the fence to expire, and remove it from the fenced list.
- *
- * fenced_buffer::mutex must be held. fenced_buffer_list::mutex must not be
- * held -- it will
- */
static INLINE enum pipe_error
-fenced_buffer_finish_locked(struct fenced_buffer_list *fenced_list,
- struct fenced_buffer *fenced_buf)
+_fenced_buffer_finish(struct fenced_buffer *fenced_buf)
{
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
struct pb_fence_ops *ops = fenced_list->ops;
- enum pipe_error ret = PIPE_ERROR;
#if 0
debug_warning("waiting for GPU");
#endif
- assert(pipe_is_referenced(&fenced_buf->base.base.reference));
assert(fenced_buf->fence);
-
- /* Acquire the global lock */
- pipe_mutex_unlock(fenced_buf->mutex);
- pipe_mutex_lock(fenced_list->mutex);
- pipe_mutex_lock(fenced_buf->mutex);
-
if(fenced_buf->fence) {
- if(ops->fence_finish(ops, fenced_buf->fence, 0) == 0) {
- /* Remove from the fenced list */
- /* TODO: remove consequents */
- fenced_buffer_remove_locked(fenced_list, fenced_buf);
-
- p_atomic_dec(&fenced_buf->base.base.reference.count);
- assert(pipe_is_referenced(&fenced_buf->base.base.reference));
-
- fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
-
- ret = PIPE_OK;
+ if(ops->fence_finish(ops, fenced_buf->fence, 0) != 0) {
+ return PIPE_ERROR;
}
+ /* Remove from the fenced list */
+ /* TODO: remove consequents */
+ _fenced_buffer_remove(fenced_list, fenced_buf);
}
- pipe_mutex_unlock(fenced_list->mutex);
-
- return ret;
+ fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
+ return PIPE_OK;
}
@@ -237,7 +215,7 @@ fenced_buffer_finish_locked(struct fenced_buffer_list *fenced_list,
* Free as many fenced buffers from the list head as possible.
*/
static void
-fenced_buffer_list_check_free_locked(struct fenced_buffer_list *fenced_list,
+_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
int wait)
{
struct pb_fence_ops *ops = fenced_list->ops;
@@ -251,30 +229,21 @@ fenced_buffer_list_check_free_locked(struct fenced_buffer_list *fenced_list,
while(curr != &fenced_list->delayed) {
fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
- pipe_mutex_lock(fenced_buf->mutex);
-
if(fenced_buf->fence != prev_fence) {
int signaled;
if (wait)
signaled = ops->fence_finish(ops, fenced_buf->fence, 0);
else
signaled = ops->fence_signalled(ops, fenced_buf->fence, 0);
- if (signaled != 0) {
- pipe_mutex_unlock(fenced_buf->mutex);
+ if (signaled != 0)
break;
- }
prev_fence = fenced_buf->fence;
}
else {
assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0);
}
- fenced_buffer_remove_locked(fenced_list, fenced_buf);
- pipe_mutex_unlock(fenced_buf->mutex);
-
- pb_buf = &fenced_buf->base;
- pb_reference(&pb_buf, NULL);
-
+ _fenced_buffer_remove(fenced_list, fenced_buf);
curr = next;
next = curr->next;
@@ -288,25 +257,30 @@ fenced_buffer_destroy(struct pb_buffer *buf)
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
struct fenced_buffer_list *fenced_list = fenced_buf->list;
- assert(!pipe_is_referenced(&fenced_buf->base.base.reference));
- assert(!fenced_buf->fence);
-
-#ifdef DEBUG
pipe_mutex_lock(fenced_list->mutex);
- assert(fenced_buf->head.prev);
- assert(fenced_buf->head.next);
- LIST_DEL(&fenced_buf->head);
- assert(fenced_list->numUnfenced);
- --fenced_list->numUnfenced;
+ assert(!pipe_is_referenced(&fenced_buf->base.base.reference));
+ if (fenced_buf->fence) {
+ struct pb_fence_ops *ops = fenced_list->ops;
+ if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) {
+ struct list_head *curr, *prev;
+ curr = &fenced_buf->head;
+ prev = curr->prev;
+ do {
+ fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
+ assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0);
+ _fenced_buffer_remove(fenced_list, fenced_buf);
+ curr = prev;
+ prev = curr->prev;
+ } while (curr != &fenced_list->delayed);
+ }
+ else {
+ /* delay destruction */
+ }
+ }
+ else {
+ _fenced_buffer_destroy(fenced_buf);
+ }
pipe_mutex_unlock(fenced_list->mutex);
-#else
- (void)fenced_list;
-#endif
-
- pb_reference(&fenced_buf->buffer, NULL);
-
- pipe_mutex_destroy(fenced_buf->mutex);
- FREE(fenced_buf);
}
@@ -317,23 +291,24 @@ fenced_buffer_map(struct pb_buffer *buf,
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
struct fenced_buffer_list *fenced_list = fenced_buf->list;
struct pb_fence_ops *ops = fenced_list->ops;
- void *map = NULL;
-
- pipe_mutex_lock(fenced_buf->mutex);
+ void *map;
assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE));
/* Serialize writes */
if((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) ||
((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) && (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) {
- if((flags & PIPE_BUFFER_USAGE_DONTBLOCK) &&
- ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) {
+ if(flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
/* Don't wait for the GPU to finish writing */
- goto finish;
+ if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0)
+ _fenced_buffer_remove(fenced_list, fenced_buf);
+ else
+ return NULL;
+ }
+ else {
+ /* Wait for the GPU to finish writing */
+ _fenced_buffer_finish(fenced_buf);
}
-
- /* Wait for the GPU to finish writing */
- fenced_buffer_finish_locked(fenced_list, fenced_buf);
}
#if 0
@@ -350,9 +325,6 @@ fenced_buffer_map(struct pb_buffer *buf,
fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE;
}
-finish:
- pipe_mutex_unlock(fenced_buf->mutex);
-
return map;
}
@@ -361,9 +333,6 @@ static void
fenced_buffer_unmap(struct pb_buffer *buf)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
-
- pipe_mutex_lock(fenced_buf->mutex);
-
assert(fenced_buf->mapcount);
if(fenced_buf->mapcount) {
pb_unmap(fenced_buf->buffer);
@@ -371,8 +340,6 @@ fenced_buffer_unmap(struct pb_buffer *buf)
if(!fenced_buf->mapcount)
fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE;
}
-
- pipe_mutex_unlock(fenced_buf->mutex);
}
@@ -384,14 +351,11 @@ fenced_buffer_validate(struct pb_buffer *buf,
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
enum pipe_error ret;
- pipe_mutex_lock(fenced_buf->mutex);
-
if(!vl) {
/* invalidate */
fenced_buf->vl = NULL;
fenced_buf->validation_flags = 0;
- ret = PIPE_OK;
- goto finish;
+ return PIPE_OK;
}
assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE);
@@ -399,17 +363,14 @@ fenced_buffer_validate(struct pb_buffer *buf,
flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE;
/* Buffer cannot be validated in two different lists */
- if(fenced_buf->vl && fenced_buf->vl != vl) {
- ret = PIPE_ERROR_RETRY;
- goto finish;
- }
+ if(fenced_buf->vl && fenced_buf->vl != vl)
+ return PIPE_ERROR_RETRY;
#if 0
/* Do not validate if buffer is still mapped */
if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
/* TODO: wait for the thread that mapped the buffer to unmap it */
- ret = PIPE_ERROR_RETRY;
- goto finish;
+ return PIPE_ERROR_RETRY;
}
/* Final sanity checking */
assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE));
@@ -419,21 +380,17 @@ fenced_buffer_validate(struct pb_buffer *buf,
if(fenced_buf->vl == vl &&
(fenced_buf->validation_flags & flags) == flags) {
/* Nothing to do -- buffer already validated */
- ret = PIPE_OK;
- goto finish;
+ return PIPE_OK;
}
ret = pb_validate(fenced_buf->buffer, vl, flags);
if (ret != PIPE_OK)
- goto finish;
+ return ret;
fenced_buf->vl = vl;
fenced_buf->validation_flags |= flags;
-finish:
- pipe_mutex_unlock(fenced_buf->mutex);
-
- return ret;
+ return PIPE_OK;
}
@@ -448,36 +405,29 @@ fenced_buffer_fence(struct pb_buffer *buf,
fenced_buf = fenced_buffer(buf);
fenced_list = fenced_buf->list;
ops = fenced_list->ops;
-
- pipe_mutex_lock(fenced_list->mutex);
- pipe_mutex_lock(fenced_buf->mutex);
-
- assert(pipe_is_referenced(&fenced_buf->base.base.reference));
-
- if(fence != fenced_buf->fence) {
- assert(fenced_buf->vl);
- assert(fenced_buf->validation_flags);
-
- if (fenced_buf->fence) {
- fenced_buffer_remove_locked(fenced_list, fenced_buf);
- p_atomic_dec(&fenced_buf->base.base.reference.count);
- assert(pipe_is_referenced(&fenced_buf->base.base.reference));
- }
- if (fence) {
- ops->fence_reference(ops, &fenced_buf->fence, fence);
- fenced_buf->flags |= fenced_buf->validation_flags;
- p_atomic_inc(&fenced_buf->base.base.reference.count);
- fenced_buffer_add_locked(fenced_list, fenced_buf);
- }
-
- pb_fence(fenced_buf->buffer, fence);
- fenced_buf->vl = NULL;
- fenced_buf->validation_flags = 0;
+ if(fence == fenced_buf->fence) {
+ /* Nothing to do */
+ return;
}
- pipe_mutex_unlock(fenced_buf->mutex);
+ assert(fenced_buf->vl);
+ assert(fenced_buf->validation_flags);
+
+ pipe_mutex_lock(fenced_list->mutex);
+ if (fenced_buf->fence)
+ _fenced_buffer_remove(fenced_list, fenced_buf);
+ if (fence) {
+ ops->fence_reference(ops, &fenced_buf->fence, fence);
+ fenced_buf->flags |= fenced_buf->validation_flags;
+ _fenced_buffer_add(fenced_buf);
+ }
pipe_mutex_unlock(fenced_list->mutex);
+
+ pb_fence(fenced_buf->buffer, fence);
+
+ fenced_buf->vl = NULL;
+ fenced_buf->validation_flags = 0;
}
@@ -487,7 +437,6 @@ fenced_buffer_get_base_buffer(struct pb_buffer *buf,
pb_size *offset)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- /* NOTE: accesses immutable members only -- mutex not necessary */
pb_get_base_buffer(fenced_buf->buffer, base_buf, offset);
}
@@ -527,8 +476,6 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list,
buf->buffer = buffer;
buf->list = fenced_list;
- pipe_mutex_init(buf->mutex);
-
#ifdef DEBUG
pipe_mutex_lock(fenced_list->mutex);
LIST_ADDTAIL(&buf->head, &fenced_list->unfenced);
@@ -570,7 +517,7 @@ fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
int wait)
{
pipe_mutex_lock(fenced_list->mutex);
- fenced_buffer_list_check_free_locked(fenced_list, wait);
+ _fenced_buffer_list_check_free(fenced_list, wait);
pipe_mutex_unlock(fenced_list->mutex);
}
@@ -592,13 +539,11 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
next = curr->next;
while(curr != &fenced_list->unfenced) {
fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
- pipe_mutex_lock(fenced_buf->mutex);
assert(!fenced_buf->fence);
debug_printf("%10p %7u %7u\n",
(void *) fenced_buf,
fenced_buf->base.base.size,
p_atomic_read(&fenced_buf->base.base.reference.count));
- pipe_mutex_unlock(fenced_buf->mutex);
curr = next;
next = curr->next;
}
@@ -608,7 +553,6 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
while(curr != &fenced_list->delayed) {
int signaled;
fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
- pipe_mutex_lock(fenced_buf->mutex);
signaled = ops->fence_signalled(ops, fenced_buf->fence, 0);
debug_printf("%10p %7u %7u %10p %s\n",
(void *) fenced_buf,
@@ -616,7 +560,6 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
p_atomic_read(&fenced_buf->base.base.reference.count),
(void *) fenced_buf->fence,
signaled == 0 ? "y" : "n");
- pipe_mutex_unlock(fenced_buf->mutex);
curr = next;
next = curr->next;
}
@@ -637,8 +580,8 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list)
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
sched_yield();
#endif
+ _fenced_buffer_list_check_free(fenced_list, 1);
pipe_mutex_lock(fenced_list->mutex);
- fenced_buffer_list_check_free_locked(fenced_list, 1);
}
#ifdef DEBUG
@@ -646,7 +589,6 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list)
#endif
pipe_mutex_unlock(fenced_list->mutex);
- pipe_mutex_destroy(fenced_list->mutex);
fenced_list->ops->destroy(fenced_list->ops);
diff --git a/src/gallium/auxiliary/rbug/Makefile b/src/gallium/auxiliary/rbug/Makefile
deleted file mode 100644
index cd12e8468f..0000000000
--- a/src/gallium/auxiliary/rbug/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = rbug
-
-C_SOURCES = \
- rbug_connection.c \
- rbug_core.c \
- rbug_texture.c \
- rbug_context.c \
- rbug_shader.c \
- rbug_demarshal.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/rbug/SConscript b/src/gallium/auxiliary/rbug/SConscript
deleted file mode 100644
index 4a9afb45d3..0000000000
--- a/src/gallium/auxiliary/rbug/SConscript
+++ /dev/null
@@ -1,14 +0,0 @@
-Import('*')
-
-rbug = env.ConvenienceLibrary(
- target = 'rbug',
- source = [
- 'rbug_core.c',
- 'rbug_shader.c',
- 'rbug_context.c',
- 'rbug_texture.c',
- 'rbug_demarshal.c',
- 'rbug_connection.c',
- ])
-
-auxiliaries.insert(0, rbug)
diff --git a/src/gallium/auxiliary/rbug/rbug_context.h b/src/gallium/auxiliary/rbug/rbug_context.h
index da61c2365b..03126d6b12 100644
--- a/src/gallium/auxiliary/rbug/rbug_context.h
+++ b/src/gallium/auxiliary/rbug/rbug_context.h
@@ -46,7 +46,7 @@ typedef enum
RBUG_BLOCK_BEFORE = 1,
RBUG_BLOCK_AFTER = 2,
RBUG_BLOCK_RULE = 4,
- RBUG_BLOCK_MASK = 7,
+ RBUG_BLOCK_MASK = 7
} rbug_block_t;
struct rbug_proto_context_list
diff --git a/src/gallium/auxiliary/rbug/rbug_proto.h b/src/gallium/auxiliary/rbug/rbug_proto.h
index d273be0166..4f3eb75dc4 100644
--- a/src/gallium/auxiliary/rbug/rbug_proto.h
+++ b/src/gallium/auxiliary/rbug/rbug_proto.h
@@ -65,7 +65,7 @@ enum rbug_opcode
RBUG_OP_SHADER_DISABLE = 770,
RBUG_OP_SHADER_REPLACE = 771,
RBUG_OP_SHADER_LIST_REPLY = -768,
- RBUG_OP_SHADER_INFO_REPLY = -769,
+ RBUG_OP_SHADER_INFO_REPLY = -769
};
/**
diff --git a/src/gallium/auxiliary/rtasm/Makefile b/src/gallium/auxiliary/rtasm/Makefile
deleted file mode 100644
index ab8ea464c6..0000000000
--- a/src/gallium/auxiliary/rtasm/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = rtasm
-
-C_SOURCES = \
- rtasm_cpu.c \
- rtasm_execmem.c \
- rtasm_x86sse.c \
- rtasm_ppc.c \
- rtasm_ppc_spe.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript
deleted file mode 100644
index eb48368acc..0000000000
--- a/src/gallium/auxiliary/rtasm/SConscript
+++ /dev/null
@@ -1,13 +0,0 @@
-Import('*')
-
-rtasm = env.ConvenienceLibrary(
- target = 'rtasm',
- source = [
- 'rtasm_cpu.c',
- 'rtasm_execmem.c',
- 'rtasm_x86sse.c',
- 'rtasm_ppc.c',
- 'rtasm_ppc_spe.c',
- ])
-
-auxiliaries.insert(0, rtasm)
diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c
index 01811d5011..ffed768f97 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c
@@ -41,6 +41,12 @@
#define MAP_ANONYMOUS MAP_ANON
#endif
+#if defined(PIPE_OS_WINDOWS)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+#endif
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
@@ -118,7 +124,29 @@ rtasm_exec_free(void *addr)
}
-#else /* PIPE_OS_LINUX || PIPE_OS_BSD || PIPE_OS_SOLARIS */
+#elif defined(PIPE_OS_WINDOWS)
+
+
+/*
+ * Avoid Data Execution Prevention.
+ */
+
+void *
+rtasm_exec_malloc(size_t size)
+{
+ return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+}
+
+
+void
+rtasm_exec_free(void *addr)
+{
+ VirtualFree(addr, 0, MEM_RELEASE);
+}
+
+
+#else
+
/*
* Just use regular memory.
@@ -138,4 +166,4 @@ rtasm_exec_free(void *addr)
}
-#endif /* PIPE_OS_LINUX || PIPE_OS_BSD || PIPE_OS_SOLARIS */
+#endif
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
index 1acf3c373e..f675427d98 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
@@ -673,6 +673,13 @@ void x86_and( struct x86_function *p,
emit_op_modrm( p, 0x23, 0x21, dst, src );
}
+void x86_div( 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, 6), src);
+}
+
/***********************************************************************
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
index 731a651796..f7612d416a 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
@@ -244,6 +244,7 @@ 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 x86_div( struct x86_function *p, struct x86_reg src );
void x86_cdecl_caller_push_regs( struct x86_function *p );
diff --git a/src/gallium/auxiliary/sct/Makefile b/src/gallium/auxiliary/sct/Makefile
deleted file mode 100644
index a7d111b689..0000000000
--- a/src/gallium/auxiliary/sct/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = sct
-
-C_SOURCES = \
- sct.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/sct/SConscript b/src/gallium/auxiliary/sct/SConscript
deleted file mode 100644
index 76927d973f..0000000000
--- a/src/gallium/auxiliary/sct/SConscript
+++ /dev/null
@@ -1,9 +0,0 @@
-Import('*')
-
-sct = env.ConvenienceLibrary(
- target = 'sct',
- source = [
- 'sct.c'
- ])
-
-auxiliaries.insert(0, sct)
diff --git a/src/gallium/auxiliary/sct/sct.c b/src/gallium/auxiliary/sct/sct.c
deleted file mode 100644
index 722d2b7e66..0000000000
--- a/src/gallium/auxiliary/sct/sct.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/**************************************************************************
- *
- * 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 "util/u_memory.h"
-#include "pipe/p_state.h"
-#include "sct.h"
-
-
-struct texture_list
-{
- struct pipe_texture *texture;
- struct texture_list *next;
-};
-
-
-
-#define MAX_SURFACES ((PIPE_MAX_COLOR_BUFS) + 1)
-
-struct sct_context
-{
- const struct pipe_context *context;
-
- /** surfaces the context is drawing into */
- struct pipe_surface *surfaces[MAX_SURFACES];
-
- /** currently bound textures */
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
-
- /** previously bound textures, used but not flushed */
- struct texture_list *textures_used;
-
- boolean needs_flush;
-
- struct sct_context *next;
-};
-
-
-
-struct sct_surface
-{
- const struct pipe_surface *surface;
-
- /** list of contexts drawing to this surface */
- struct sct_context_list *contexts;
-
- struct sct_surface *next;
-};
-
-
-
-/**
- * Find the surface_info for the given pipe_surface
- */
-static struct sct_surface *
-find_surface_info(struct surface_context_tracker *sct,
- const struct pipe_surface *surface)
-{
- struct sct_surface *si;
- for (si = sct->surfaces; si; si = si->next)
- if (si->surface == surface)
- return si;
- return NULL;
-}
-
-
-/**
- * As above, but create new surface_info if surface is new.
- */
-static struct sct_surface *
-find_create_surface_info(struct surface_context_tracker *sct,
- const struct pipe_surface *surface)
-{
- struct sct_surface *si = find_surface_info(sct, surface);
- if (si)
- return si;
-
- /* alloc new */
- si = CALLOC_STRUCT(sct_surface);
- if (si) {
- si->surface = surface;
-
- /* insert at head */
- si->next = sct->surfaces;
- sct->surfaces = si;
- }
-
- return si;
-}
-
-
-/**
- * Find a context_info for the given context.
- */
-static struct sct_context *
-find_context_info(struct surface_context_tracker *sct,
- const struct pipe_context *context)
-{
- struct sct_context *ci;
- for (ci = sct->contexts; ci; ci = ci->next)
- if (ci->context == context)
- return ci;
- return NULL;
-}
-
-
-/**
- * As above, but create new context_info if context is new.
- */
-static struct sct_context *
-find_create_context_info(struct surface_context_tracker *sct,
- const struct pipe_context *context)
-{
- struct sct_context *ci = find_context_info(sct, context);
- if (ci)
- return ci;
-
- /* alloc new */
- ci = CALLOC_STRUCT(sct_context);
- if (ci) {
- ci->context = context;
-
- /* insert at head */
- ci->next = sct->contexts;
- sct->contexts = ci;
- }
-
- return ci;
-}
-
-
-/**
- * Is the context already bound to the surface?
- */
-static boolean
-find_surface_context(const struct sct_surface *si,
- const struct pipe_context *context)
-{
- const struct sct_context_list *cl;
- for (cl = si->contexts; cl; cl = cl->next) {
- if (cl->context == context) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-
-/**
- * Add a context to the list of contexts associated with a surface.
- */
-static void
-add_context_to_surface(struct sct_surface *si,
- const struct pipe_context *context)
-{
- struct sct_context_list *cl = CALLOC_STRUCT(sct_context_list);
- if (cl) {
- cl->context = context;
- /* insert at head of list of contexts */
- cl->next = si->contexts;
- si->contexts = cl;
- }
-}
-
-
-/**
- * Remove a context from the list of contexts associated with a surface.
- */
-static void
-remove_context_from_surface(struct sct_surface *si,
- const struct pipe_context *context)
-{
- struct sct_context_list *prev = NULL, *curr, *next;
-
- for (curr = si->contexts; curr; curr = next) {
- if (curr->context == context) {
- /* remove */
- if (prev)
- prev->next = curr->next;
- else
- si->contexts = curr->next;
- next = curr->next;
- FREE(curr);
- }
- else {
- prev = curr;
- next = curr->next;
- }
- }
-}
-
-
-/**
- * Unbind context from surface.
- */
-static void
-unbind_context_surface(struct surface_context_tracker *sct,
- struct pipe_context *context,
- struct pipe_surface *surface)
-{
- struct sct_surface *si = find_surface_info(sct, surface);
- if (si) {
- remove_context_from_surface(si, context);
- }
-}
-
-
-/**
- * Bind context to a set of surfaces (color + Z).
- * Like MakeCurrent().
- */
-void
-sct_bind_surfaces(struct surface_context_tracker *sct,
- struct pipe_context *context,
- uint num_surf,
- struct pipe_surface **surfaces)
-{
- struct sct_context *ci = find_create_context_info(sct, context);
- uint i;
-
- if (!ci) {
- return; /* out of memory */
- }
-
- /* unbind currently bound surfaces */
- for (i = 0; i < MAX_SURFACES; i++) {
- if (ci->surfaces[i]) {
- unbind_context_surface(sct, context, ci->surfaces[i]);
- }
- }
-
- /* bind new surfaces */
- for (i = 0; i < num_surf; i++) {
- struct sct_surface *si = find_create_surface_info(sct, surfaces[i]);
- if (!find_surface_context(si, context)) {
- add_context_to_surface(si, context);
- }
- }
-}
-
-
-/**
- * Return list of contexts bound to a surface.
- */
-const struct sct_context_list *
-sct_get_surface_contexts(struct surface_context_tracker *sct,
- const struct pipe_surface *surface)
-{
- const struct sct_surface *si = find_surface_info(sct, surface);
- return si->contexts;
-}
-
-
-
-static boolean
-find_texture(const struct sct_context *ci,
- const struct pipe_texture *texture)
-{
- const struct texture_list *tl;
-
- for (tl = ci->textures_used; tl; tl = tl->next) {
- if (tl->texture == texture) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-
-/**
- * Add the given texture to the context's list of used textures.
- */
-static void
-add_texture_used(struct sct_context *ci,
- struct pipe_texture *texture)
-{
- if (!find_texture(ci, texture)) {
- /* add to list */
- struct texture_list *tl = CALLOC_STRUCT(texture_list);
- if (tl) {
- pipe_texture_reference(&tl->texture, texture);
- /* insert at head */
- tl->next = ci->textures_used;
- ci->textures_used = tl;
- }
- }
-}
-
-
-/**
- * Bind a texture to a rendering context.
- */
-void
-sct_bind_texture(struct surface_context_tracker *sct,
- struct pipe_context *context,
- uint unit,
- struct pipe_texture *tex)
-{
- struct sct_context *ci = find_context_info(sct, context);
-
- if (ci->textures[unit] != tex) {
- /* put texture on the 'used' list */
- add_texture_used(ci, tex);
- /* bind new */
- pipe_texture_reference(&ci->textures[unit], tex);
- }
-}
-
-
-/**
- * Check if the given texture has been used by the rendering context
- * since the last call to sct_flush_textures().
- */
-boolean
-sct_is_texture_used(struct surface_context_tracker *sct,
- const struct pipe_context *context,
- const struct pipe_texture *texture)
-{
- const struct sct_context *ci = find_context_info(sct, context);
- return find_texture(ci, texture);
-}
-
-
-/**
- * To be called when the image contents of a texture are changed, such
- * as for gl[Copy]TexSubImage().
- * XXX this may not be needed
- */
-void
-sct_update_texture(struct pipe_texture *tex)
-{
-
-}
-
-
-/**
- * When a scene is flushed/rendered we can release the list of
- * used textures.
- */
-void
-sct_flush_textures(struct surface_context_tracker *sct,
- struct pipe_context *context)
-{
- struct sct_context *ci = find_context_info(sct, context);
- struct texture_list *tl, *next;
- uint i;
-
- for (tl = ci->textures_used; tl; tl = next) {
- next = tl->next;
- pipe_texture_reference(&tl->texture, NULL);
- FREE(tl);
- }
- ci->textures_used = NULL;
-
- /* put the currently bound textures on the 'used' list */
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- add_texture_used(ci, ci->textures[i]);
- }
-}
-
-
-
-void
-sct_destroy_context(struct surface_context_tracker *sct,
- struct pipe_context *context)
-{
- /* XXX should we require an unbinding first? */
- {
- struct sct_surface *si;
- for (si = sct->surfaces; si; si = si->next) {
- remove_context_from_surface(si, context);
- }
- }
-
- /* remove context from context_info list */
- {
- struct sct_context *ci, *next, *prev = NULL;
- for (ci = sct->contexts; ci; ci = next) {
- next = ci->next;
- if (ci->context == context) {
- if (prev)
- prev->next = ci->next;
- else
- sct->contexts = ci->next;
- FREE(ci);
- }
- else {
- prev = ci;
- }
- }
- }
-
-}
-
-
-void
-sct_destroy_surface(struct surface_context_tracker *sct,
- struct pipe_surface *surface)
-{
- if (1) {
- /* debug/sanity: no context should be bound to surface */
- struct sct_context *ci;
- uint i;
- for (ci = sct->contexts; ci; ci = ci->next) {
- for (i = 0; i < MAX_SURFACES; i++) {
- assert(ci->surfaces[i] != surface);
- }
- }
- }
-
- /* remove surface from sct_surface list */
- {
- struct sct_surface *si, *next, *prev = NULL;
- for (si = sct->surfaces; si; si = next) {
- next = si->next;
- if (si->surface == surface) {
- /* unlink */
- if (prev)
- prev->next = si->next;
- else
- sct->surfaces = si->next;
- FREE(si);
- }
- else {
- prev = si;
- }
- }
- }
-}
diff --git a/src/gallium/auxiliary/sct/sct.h b/src/gallium/auxiliary/sct/sct.h
deleted file mode 100644
index cf7c4d3bdf..0000000000
--- a/src/gallium/auxiliary/sct/sct.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-/**
- * Surface/Context Tracking
- *
- * For some drivers, we need to monitor the binding between contexts and
- * surfaces/textures.
- * This code may evolve quite a bit...
- */
-
-
-#ifndef SCT_H
-#define SCT_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct pipe_context;
-struct pipe_surface;
-
-struct sct_context;
-struct sct_surface;
-
-
-/**
- * Per-device info, basically
- */
-struct surface_context_tracker
-{
- struct sct_context *contexts;
- struct sct_surface *surfaces;
-};
-
-
-
-/**
- * Simple linked list of contexts
- */
-struct sct_context_list
-{
- const struct pipe_context *context;
- struct sct_context_list *next;
-};
-
-
-
-extern void
-sct_bind_surfaces(struct surface_context_tracker *sct,
- struct pipe_context *context,
- uint num_surf,
- struct pipe_surface **surfaces);
-
-
-extern void
-sct_bind_texture(struct surface_context_tracker *sct,
- struct pipe_context *context,
- uint unit,
- struct pipe_texture *texture);
-
-
-extern void
-sct_update_texture(struct pipe_texture *tex);
-
-
-extern boolean
-sct_is_texture_used(struct surface_context_tracker *sct,
- const struct pipe_context *context,
- const struct pipe_texture *texture);
-
-extern void
-sct_flush_textures(struct surface_context_tracker *sct,
- struct pipe_context *context);
-
-
-extern const struct sct_context_list *
-sct_get_surface_contexts(struct surface_context_tracker *sct,
- const struct pipe_surface *surf);
-
-
-extern void
-sct_destroy_context(struct surface_context_tracker *sct,
- struct pipe_context *context);
-
-
-extern void
-sct_destroy_surface(struct surface_context_tracker *sct,
- struct pipe_surface *surface);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SCT_H */
diff --git a/src/gallium/auxiliary/sct/usage.c b/src/gallium/auxiliary/sct/usage.c
deleted file mode 100644
index 6227f19962..0000000000
--- a/src/gallium/auxiliary/sct/usage.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* surface / context tracking */
-
-
-/*
-
-context A:
- render to texture T
-
-context B:
- texture from T
-
------------------------
-
-flush surface:
- which contexts are bound to the surface?
-
------------------------
-
-glTexSubImage():
- which contexts need to be flushed?
-
- */
-
-
-/*
-
-in MakeCurrent():
-
- call sct_bind_surfaces(context, list of surfaces) to update the
- dependencies between context and surfaces
-
-
-in SurfaceFlush(), or whatever it is in D3D:
-
- call sct_get_surface_contexts(surface) to get a list of contexts
- which are currently bound to the surface.
-
-
-
-in BindTexture():
-
- call sct_bind_texture(context, texture) to indicate that the texture
- is used in the scene.
-
-
-in glTexSubImage() or RenderToTexture():
-
- call sct_is_texture_used(context, texture) to determine if the texture
- has been used in the scene, but the scene's not flushed. If TRUE is
- returned it means the scene has to be rendered/flushed before the contents
- of the texture can be changed.
-
-
-in psb_scene_flush/terminate():
-
- call sct_flush_textures(context) to tell the SCT that the textures which
- were used in the scene can be released.
-
-
-
-*/
diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile
deleted file mode 100644
index 5f0a580b09..0000000000
--- a/src/gallium/auxiliary/tgsi/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = tgsi
-
-C_SOURCES = \
- tgsi_sanity.c \
- tgsi_build.c \
- tgsi_dump.c \
- tgsi_exec.c \
- tgsi_info.c \
- tgsi_iterate.c \
- tgsi_parse.c \
- tgsi_ppc.c \
- tgsi_scan.c \
- tgsi_sse2.c \
- tgsi_text.c \
- tgsi_transform.c \
- tgsi_ureg.c \
- tgsi_util.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript
deleted file mode 100644
index b6bc2924f0..0000000000
--- a/src/gallium/auxiliary/tgsi/SConscript
+++ /dev/null
@@ -1,23 +0,0 @@
-Import('*')
-
-tgsi = env.ConvenienceLibrary(
- target = 'tgsi',
- source = [
- 'tgsi_build.c',
- 'tgsi_dump.c',
- 'tgsi_dump_c.c',
- 'tgsi_exec.c',
- 'tgsi_info.c',
- 'tgsi_iterate.c',
- 'tgsi_parse.c',
- 'tgsi_sanity.c',
- 'tgsi_scan.c',
- 'tgsi_ppc.c',
- 'tgsi_sse2.c',
- 'tgsi_text.c',
- 'tgsi_transform.c',
- 'tgsi_ureg.c',
- 'tgsi_util.c',
- ])
-
-auxiliaries.insert(0, tgsi)
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index 92903fe57f..de9cbc8630 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -1025,7 +1025,7 @@ tgsi_build_full_property(
size++;
*property = tgsi_build_property(
- TGSI_PROPERTY_GS_INPUT_PRIM,
+ full_prop->Property.PropertyName,
header );
assert( full_prop->Property.NrTokens <= 8 + 1 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index 5e7e5d2ff9..d7ff262f30 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -122,12 +122,16 @@ static const char *semantic_names[] =
"GENERIC",
"NORMAL",
"FACE",
- "EDGEFLAG"
+ "EDGEFLAG",
+ "PRIM_ID",
+ "INSTANCEID"
};
static const char *immediate_type_names[] =
{
- "FLT32"
+ "FLT32",
+ "UINT32",
+ "INT32"
};
static const char *swizzle_names[] =
@@ -174,13 +178,19 @@ static const char *primitive_names[] =
static void
-_dump_register(
+_dump_register_decl(
struct dump_ctx *ctx,
uint file,
int first,
int last )
{
ENM( file, file_names );
+
+ /* all geometry shader inputs are two dimensional */
+ if (file == TGSI_FILE_INPUT &&
+ ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY)
+ TXT("[]");
+
CHR( '[' );
SID( first );
if (first != last) {
@@ -191,6 +201,52 @@ _dump_register(
}
static void
+_dump_register_dst(
+ struct dump_ctx *ctx,
+ uint file,
+ int index)
+{
+ ENM( file, file_names );
+
+ CHR( '[' );
+ SID( index );
+ CHR( ']' );
+}
+
+
+static void
+_dump_register_src(
+ struct dump_ctx *ctx,
+ const struct tgsi_full_src_register *src )
+{
+ if (src->Register.Indirect) {
+ ENM( src->Register.File, file_names );
+ CHR( '[' );
+ ENM( src->Indirect.File, file_names );
+ CHR( '[' );
+ SID( src->Indirect.Index );
+ TXT( "]." );
+ ENM( src->Indirect.SwizzleX, swizzle_names );
+ if (src->Register.Index != 0) {
+ if (src->Register.Index > 0)
+ CHR( '+' );
+ SID( src->Register.Index );
+ }
+ CHR( ']' );
+ } else {
+ ENM( src->Register.File, file_names );
+ CHR( '[' );
+ SID( src->Register.Index );
+ CHR( ']' );
+ }
+ if (src->Register.Dimension) {
+ CHR( '[' );
+ SID( src->Dimension.Index );
+ CHR( ']' );
+ }
+}
+
+static void
_dump_register_ind(
struct dump_ctx *ctx,
uint file,
@@ -244,7 +300,7 @@ iter_declaration(
TXT( "DCL " );
- _dump_register(
+ _dump_register_decl(
ctx,
decl->Declaration.File,
decl->Range.First,
@@ -359,6 +415,12 @@ iter_immediate(
case TGSI_IMM_FLOAT32:
FLT( imm->u[i].Float );
break;
+ case TGSI_IMM_UINT32:
+ UID(imm->u[i].Uint);
+ break;
+ case TGSI_IMM_INT32:
+ SID(imm->u[i].Int);
+ break;
default:
assert( 0 );
}
@@ -435,10 +497,9 @@ iter_instruction(
dst->Indirect.SwizzleX );
}
else {
- _dump_register(
+ _dump_register_dst(
ctx,
dst->Register.File,
- dst->Register.Index,
dst->Register.Index );
}
_dump_writemask( ctx, dst->Register.WriteMask );
@@ -454,26 +515,11 @@ iter_instruction(
CHR( ' ' );
if (src->Register.Negate)
- TXT( "-(" );
+ CHR( '-' );
if (src->Register.Absolute)
CHR( '|' );
- if (src->Register.Indirect) {
- _dump_register_ind(
- ctx,
- src->Register.File,
- src->Register.Index,
- src->Indirect.File,
- src->Indirect.Index,
- src->Indirect.SwizzleX );
- }
- else {
- _dump_register(
- ctx,
- src->Register.File,
- src->Register.Index,
- src->Register.Index );
- }
+ _dump_register_src(ctx, src);
if (src->Register.SwizzleX != TGSI_SWIZZLE_X ||
src->Register.SwizzleY != TGSI_SWIZZLE_Y ||
@@ -488,8 +534,6 @@ iter_instruction(
if (src->Register.Absolute)
CHR( '|' );
- if (src->Register.Negate)
- CHR( ')' );
first_reg = FALSE;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 123117cb0a..118a638ab4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -2,6 +2,7 @@
*
* Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2009-2010 VMware, Inc. All rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -60,6 +61,7 @@
#include "util/u_memory.h"
#include "util/u_math.h"
+
#define FAST_MATH 1
#define TILE_TOP_LEFT 0
@@ -67,11 +69,329 @@
#define TILE_BOTTOM_LEFT 2
#define TILE_BOTTOM_RIGHT 3
+static void
+micro_abs(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = fabsf(src->f[0]);
+ dst->f[1] = fabsf(src->f[1]);
+ dst->f[2] = fabsf(src->f[2]);
+ dst->f[3] = fabsf(src->f[3]);
+}
+
+static void
+micro_arl(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = (int)floorf(src->f[0]);
+ dst->i[1] = (int)floorf(src->f[1]);
+ dst->i[2] = (int)floorf(src->f[2]);
+ dst->i[3] = (int)floorf(src->f[3]);
+}
+
+static void
+micro_arr(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = (int)floorf(src->f[0] + 0.5f);
+ dst->i[1] = (int)floorf(src->f[1] + 0.5f);
+ dst->i[2] = (int)floorf(src->f[2] + 0.5f);
+ dst->i[3] = (int)floorf(src->f[3] + 0.5f);
+}
+
+static void
+micro_ceil(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = ceilf(src->f[0]);
+ dst->f[1] = ceilf(src->f[1]);
+ dst->f[2] = ceilf(src->f[2]);
+ dst->f[3] = ceilf(src->f[3]);
+}
+
+static void
+micro_cos(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = cosf(src->f[0]);
+ dst->f[1] = cosf(src->f[1]);
+ dst->f[2] = cosf(src->f[2]);
+ dst->f[3] = cosf(src->f[3]);
+}
+
+static void
+micro_ddx(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] =
+ dst->f[1] =
+ dst->f[2] =
+ dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT];
+}
+
+static void
+micro_ddy(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] =
+ dst->f[1] =
+ dst->f[2] =
+ dst->f[3] = src->f[TILE_BOTTOM_LEFT] - src->f[TILE_TOP_LEFT];
+}
+
+static void
+micro_exp2(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+#if FAST_MATH
+ dst->f[0] = util_fast_exp2(src->f[0]);
+ dst->f[1] = util_fast_exp2(src->f[1]);
+ dst->f[2] = util_fast_exp2(src->f[2]);
+ dst->f[3] = util_fast_exp2(src->f[3]);
+#else
+#if DEBUG
+ /* Inf is okay for this instruction, so clamp it to silence assertions. */
+ uint i;
+ union tgsi_exec_channel clamped;
+
+ for (i = 0; i < 4; i++) {
+ if (src->f[i] > 127.99999f) {
+ clamped.f[i] = 127.99999f;
+ } else if (src->f[i] < -126.99999f) {
+ clamped.f[i] = -126.99999f;
+ } else {
+ clamped.f[i] = src->f[i];
+ }
+ }
+ src = &clamped;
+#endif /* DEBUG */
+
+ dst->f[0] = powf(2.0f, src->f[0]);
+ dst->f[1] = powf(2.0f, src->f[1]);
+ dst->f[2] = powf(2.0f, src->f[2]);
+ dst->f[3] = powf(2.0f, src->f[3]);
+#endif /* FAST_MATH */
+}
+
+static void
+micro_flr(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = floorf(src->f[0]);
+ dst->f[1] = floorf(src->f[1]);
+ dst->f[2] = floorf(src->f[2]);
+ dst->f[3] = floorf(src->f[3]);
+}
+
+static void
+micro_frc(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src->f[0] - floorf(src->f[0]);
+ dst->f[1] = src->f[1] - floorf(src->f[1]);
+ dst->f[2] = src->f[2] - floorf(src->f[2]);
+ dst->f[3] = src->f[3] - floorf(src->f[3]);
+}
+
+static void
+micro_iabs(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = src->i[0] >= 0 ? src->i[0] : -src->i[0];
+ dst->i[1] = src->i[1] >= 0 ? src->i[1] : -src->i[1];
+ dst->i[2] = src->i[2] >= 0 ? src->i[2] : -src->i[2];
+ dst->i[3] = src->i[3] >= 0 ? src->i[3] : -src->i[3];
+}
+
+static void
+micro_ineg(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = -src->i[0];
+ dst->i[1] = -src->i[1];
+ dst->i[2] = -src->i[2];
+ dst->i[3] = -src->i[3];
+}
+
+static void
+micro_lg2(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+#if FAST_MATH
+ dst->f[0] = util_fast_log2(src->f[0]);
+ dst->f[1] = util_fast_log2(src->f[1]);
+ dst->f[2] = util_fast_log2(src->f[2]);
+ dst->f[3] = util_fast_log2(src->f[3]);
+#else
+ dst->f[0] = logf(src->f[0]) * 1.442695f;
+ dst->f[1] = logf(src->f[1]) * 1.442695f;
+ dst->f[2] = logf(src->f[2]) * 1.442695f;
+ dst->f[3] = logf(src->f[3]) * 1.442695f;
+#endif
+}
+
+static void
+micro_lrp(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src[0].f[0] * (src[1].f[0] - src[2].f[0]) + src[2].f[0];
+ dst->f[1] = src[0].f[1] * (src[1].f[1] - src[2].f[1]) + src[2].f[1];
+ dst->f[2] = src[0].f[2] * (src[1].f[2] - src[2].f[2]) + src[2].f[2];
+ dst->f[3] = src[0].f[3] * (src[1].f[3] - src[2].f[3]) + src[2].f[3];
+}
+
+static void
+micro_mad(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src[0].f[0] * src[1].f[0] + src[2].f[0];
+ dst->f[1] = src[0].f[1] * src[1].f[1] + src[2].f[1];
+ dst->f[2] = src[0].f[2] * src[1].f[2] + src[2].f[2];
+ dst->f[3] = src[0].f[3] * src[1].f[3] + src[2].f[3];
+}
+
+static void
+micro_mov(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src->u[0];
+ dst->u[1] = src->u[1];
+ dst->u[2] = src->u[2];
+ dst->u[3] = src->u[3];
+}
+
+static void
+micro_rcp(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = 1.0f / src->f[0];
+ dst->f[1] = 1.0f / src->f[1];
+ dst->f[2] = 1.0f / src->f[2];
+ dst->f[3] = 1.0f / src->f[3];
+}
+
+static void
+micro_rnd(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = floorf(src->f[0] + 0.5f);
+ dst->f[1] = floorf(src->f[1] + 0.5f);
+ dst->f[2] = floorf(src->f[2] + 0.5f);
+ dst->f[3] = floorf(src->f[3] + 0.5f);
+}
+
+static void
+micro_rsq(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = 1.0f / sqrtf(fabsf(src->f[0]));
+ dst->f[1] = 1.0f / sqrtf(fabsf(src->f[1]));
+ dst->f[2] = 1.0f / sqrtf(fabsf(src->f[2]));
+ dst->f[3] = 1.0f / sqrtf(fabsf(src->f[3]));
+}
+
+static void
+micro_seq(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src[0].f[0] == src[1].f[0] ? 1.0f : 0.0f;
+ dst->f[1] = src[0].f[1] == src[1].f[1] ? 1.0f : 0.0f;
+ dst->f[2] = src[0].f[2] == src[1].f[2] ? 1.0f : 0.0f;
+ dst->f[3] = src[0].f[3] == src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_sge(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src[0].f[0] >= src[1].f[0] ? 1.0f : 0.0f;
+ dst->f[1] = src[0].f[1] >= src[1].f[1] ? 1.0f : 0.0f;
+ dst->f[2] = src[0].f[2] >= src[1].f[2] ? 1.0f : 0.0f;
+ dst->f[3] = src[0].f[3] >= src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_sgn(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src->f[0] < 0.0f ? -1.0f : src->f[0] > 0.0f ? 1.0f : 0.0f;
+ dst->f[1] = src->f[1] < 0.0f ? -1.0f : src->f[1] > 0.0f ? 1.0f : 0.0f;
+ dst->f[2] = src->f[2] < 0.0f ? -1.0f : src->f[2] > 0.0f ? 1.0f : 0.0f;
+ dst->f[3] = src->f[3] < 0.0f ? -1.0f : src->f[3] > 0.0f ? 1.0f : 0.0f;
+}
+
+static void
+micro_sgt(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src[0].f[0] > src[1].f[0] ? 1.0f : 0.0f;
+ dst->f[1] = src[0].f[1] > src[1].f[1] ? 1.0f : 0.0f;
+ dst->f[2] = src[0].f[2] > src[1].f[2] ? 1.0f : 0.0f;
+ dst->f[3] = src[0].f[3] > src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_sin(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = sinf(src->f[0]);
+ dst->f[1] = sinf(src->f[1]);
+ dst->f[2] = sinf(src->f[2]);
+ dst->f[3] = sinf(src->f[3]);
+}
+
+static void
+micro_sle(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src[0].f[0] <= src[1].f[0] ? 1.0f : 0.0f;
+ dst->f[1] = src[0].f[1] <= src[1].f[1] ? 1.0f : 0.0f;
+ dst->f[2] = src[0].f[2] <= src[1].f[2] ? 1.0f : 0.0f;
+ dst->f[3] = src[0].f[3] <= src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_slt(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src[0].f[0] < src[1].f[0] ? 1.0f : 0.0f;
+ dst->f[1] = src[0].f[1] < src[1].f[1] ? 1.0f : 0.0f;
+ dst->f[2] = src[0].f[2] < src[1].f[2] ? 1.0f : 0.0f;
+ dst->f[3] = src[0].f[3] < src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_sne(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = src[0].f[0] != src[1].f[0] ? 1.0f : 0.0f;
+ dst->f[1] = src[0].f[1] != src[1].f[1] ? 1.0f : 0.0f;
+ dst->f[2] = src[0].f[2] != src[1].f[2] ? 1.0f : 0.0f;
+ dst->f[3] = src[0].f[3] != src[1].f[3] ? 1.0f : 0.0f;
+}
+
+static void
+micro_trunc(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = (float)(int)src->f[0];
+ dst->f[1] = (float)(int)src->f[1];
+ dst->f[2] = (float)(int)src->f[2];
+ dst->f[3] = (float)(int)src->f[3];
+}
+
+
#define CHAN_X 0
#define CHAN_Y 1
#define CHAN_Z 2
#define CHAN_W 3
+enum tgsi_exec_datatype {
+ TGSI_EXEC_DATA_FLOAT,
+ TGSI_EXEC_DATA_INT,
+ TGSI_EXEC_DATA_UINT
+};
+
/*
* Shorthand locations of various utility registers (_I = Index, _C = Channel)
*/
@@ -123,23 +443,19 @@
/** The execution mask depends on the conditional mask and the loop mask */
#define UPDATE_EXEC_MASK(MACH) \
- MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->FuncMask
+ MACH->ExecMask = MACH->CondMask & MACH->LoopMask & MACH->ContMask & MACH->Switch.mask & MACH->FuncMask
static const union tgsi_exec_channel ZeroVec =
{ { 0.0, 0.0, 0.0, 0.0 } };
-#ifdef DEBUG
-static void
-check_inf_or_nan(const union tgsi_exec_channel *chan)
-{
- assert(!util_is_inf_or_nan(chan->f[0]));
- assert(!util_is_inf_or_nan(chan->f[1]));
- assert(!util_is_inf_or_nan(chan->f[2]));
- assert(!util_is_inf_or_nan(chan->f[3]));
-}
-#endif
+#define CHECK_INF_OR_NAN(chan) do {\
+ assert(!util_is_inf_or_nan((chan)->f[0]));\
+ assert(!util_is_inf_or_nan((chan)->f[1]));\
+ assert(!util_is_inf_or_nan((chan)->f[2]));\
+ assert(!util_is_inf_or_nan((chan)->f[3]));\
+ } while (0)
#ifdef DEBUG
@@ -292,6 +608,14 @@ tgsi_exec_machine_bind_shader(
* sizeof(struct tgsi_full_declaration));
maxDeclarations += 10;
}
+ if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_OUTPUT) {
+ unsigned reg;
+ for (reg = parse.FullToken.FullDeclaration.Range.First;
+ reg <= parse.FullToken.FullDeclaration.Range.Last;
+ ++reg) {
+ ++mach->NumOutputs;
+ }
+ }
memcpy(declarations + numDeclarations,
&parse.FullToken.FullDeclaration,
sizeof(declarations[0]));
@@ -372,6 +696,7 @@ tgsi_exec_machine_create( void )
memset(mach, 0, sizeof(*mach));
mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
+ mach->MaxGeometryShaderOutputs = TGSI_MAX_TOTAL_VERTICES;
mach->Predicates = &mach->Temps[TGSI_EXEC_TEMP_P0];
/* Setup constants. */
@@ -413,18 +738,6 @@ tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach)
align_free(mach);
}
-
-static void
-micro_abs(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = fabsf( src->f[0] );
- dst->f[1] = fabsf( src->f[1] );
- dst->f[2] = fabsf( src->f[2] );
- dst->f[3] = fabsf( src->f[3] );
-}
-
static void
micro_add(
union tgsi_exec_channel *dst,
@@ -437,76 +750,6 @@ micro_add(
dst->f[3] = src0->f[3] + src1->f[3];
}
-#if 0
-static void
-micro_iadd(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->i[0] = src0->i[0] + src1->i[0];
- dst->i[1] = src0->i[1] + src1->i[1];
- dst->i[2] = src0->i[2] + src1->i[2];
- dst->i[3] = src0->i[3] + src1->i[3];
-}
-#endif
-
-static void
-micro_and(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->u[0] = src0->u[0] & src1->u[0];
- dst->u[1] = src0->u[1] & src1->u[1];
- dst->u[2] = src0->u[2] & src1->u[2];
- dst->u[3] = src0->u[3] & src1->u[3];
-}
-
-static void
-micro_ceil(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = ceilf( src->f[0] );
- dst->f[1] = ceilf( src->f[1] );
- dst->f[2] = ceilf( src->f[2] );
- dst->f[3] = ceilf( src->f[3] );
-}
-
-static void
-micro_cos(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = cosf( src->f[0] );
- dst->f[1] = cosf( src->f[1] );
- dst->f[2] = cosf( src->f[2] );
- dst->f[3] = cosf( src->f[3] );
-}
-
-static void
-micro_ddx(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] =
- dst->f[1] =
- dst->f[2] =
- dst->f[3] = src->f[TILE_BOTTOM_RIGHT] - src->f[TILE_BOTTOM_LEFT];
-}
-
-static void
-micro_ddy(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] =
- dst->f[1] =
- dst->f[2] =
- dst->f[3] = src->f[TILE_BOTTOM_LEFT] - src->f[TILE_TOP_LEFT];
-}
-
static void
micro_div(
union tgsi_exec_channel *dst,
@@ -527,99 +770,6 @@ micro_div(
}
}
-#if 0
-static void
-micro_udiv(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->u[0] = src0->u[0] / src1->u[0];
- dst->u[1] = src0->u[1] / src1->u[1];
- dst->u[2] = src0->u[2] / src1->u[2];
- dst->u[3] = src0->u[3] / src1->u[3];
-}
-#endif
-
-static void
-micro_eq(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1,
- const union tgsi_exec_channel *src2,
- const union tgsi_exec_channel *src3 )
-{
- dst->f[0] = src0->f[0] == src1->f[0] ? src2->f[0] : src3->f[0];
- dst->f[1] = src0->f[1] == src1->f[1] ? src2->f[1] : src3->f[1];
- dst->f[2] = src0->f[2] == src1->f[2] ? src2->f[2] : src3->f[2];
- dst->f[3] = src0->f[3] == src1->f[3] ? src2->f[3] : src3->f[3];
-}
-
-#if 0
-static void
-micro_ieq(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1,
- const union tgsi_exec_channel *src2,
- const union tgsi_exec_channel *src3 )
-{
- dst->i[0] = src0->i[0] == src1->i[0] ? src2->i[0] : src3->i[0];
- dst->i[1] = src0->i[1] == src1->i[1] ? src2->i[1] : src3->i[1];
- dst->i[2] = src0->i[2] == src1->i[2] ? src2->i[2] : src3->i[2];
- dst->i[3] = src0->i[3] == src1->i[3] ? src2->i[3] : src3->i[3];
-}
-#endif
-
-static void
-micro_exp2(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src)
-{
-#if FAST_MATH
- dst->f[0] = util_fast_exp2( src->f[0] );
- dst->f[1] = util_fast_exp2( src->f[1] );
- dst->f[2] = util_fast_exp2( src->f[2] );
- dst->f[3] = util_fast_exp2( src->f[3] );
-#else
-
-#if DEBUG
- /* Inf is okay for this instruction, so clamp it to silence assertions. */
- uint i;
- union tgsi_exec_channel clamped;
-
- for (i = 0; i < 4; i++) {
- if (src->f[i] > 127.99999f) {
- clamped.f[i] = 127.99999f;
- } else if (src->f[i] < -126.99999f) {
- clamped.f[i] = -126.99999f;
- } else {
- clamped.f[i] = src->f[i];
- }
- }
- src = &clamped;
-#endif
-
- dst->f[0] = powf( 2.0f, src->f[0] );
- dst->f[1] = powf( 2.0f, src->f[1] );
- dst->f[2] = powf( 2.0f, src->f[2] );
- dst->f[3] = powf( 2.0f, src->f[3] );
-#endif
-}
-
-#if 0
-static void
-micro_f2ut(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->u[0] = (uint) src->f[0];
- dst->u[1] = (uint) src->f[1];
- dst->u[2] = (uint) src->f[2];
- dst->u[3] = (uint) src->f[3];
-}
-#endif
-
static void
micro_float_clamp(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src)
@@ -647,71 +797,6 @@ micro_float_clamp(union tgsi_exec_channel *dst,
}
static void
-micro_flr(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = floorf( src->f[0] );
- dst->f[1] = floorf( src->f[1] );
- dst->f[2] = floorf( src->f[2] );
- dst->f[3] = floorf( src->f[3] );
-}
-
-static void
-micro_frc(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = src->f[0] - floorf( src->f[0] );
- dst->f[1] = src->f[1] - floorf( src->f[1] );
- dst->f[2] = src->f[2] - floorf( src->f[2] );
- dst->f[3] = src->f[3] - floorf( src->f[3] );
-}
-
-static void
-micro_i2f(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = (float) src->i[0];
- dst->f[1] = (float) src->i[1];
- dst->f[2] = (float) src->i[2];
- dst->f[3] = (float) src->i[3];
-}
-
-static void
-micro_lg2(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
-#if FAST_MATH
- dst->f[0] = util_fast_log2( src->f[0] );
- dst->f[1] = util_fast_log2( src->f[1] );
- dst->f[2] = util_fast_log2( src->f[2] );
- dst->f[3] = util_fast_log2( src->f[3] );
-#else
- dst->f[0] = logf( src->f[0] ) * 1.442695f;
- dst->f[1] = logf( src->f[1] ) * 1.442695f;
- dst->f[2] = logf( src->f[2] ) * 1.442695f;
- dst->f[3] = logf( src->f[3] ) * 1.442695f;
-#endif
-}
-
-static void
-micro_le(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1,
- const union tgsi_exec_channel *src2,
- const union tgsi_exec_channel *src3 )
-{
- dst->f[0] = src0->f[0] <= src1->f[0] ? src2->f[0] : src3->f[0];
- dst->f[1] = src0->f[1] <= src1->f[1] ? src2->f[1] : src3->f[1];
- dst->f[2] = src0->f[2] <= src1->f[2] ? src2->f[2] : src3->f[2];
- dst->f[3] = src0->f[3] <= src1->f[3] ? src2->f[3] : src3->f[3];
-}
-
-static void
micro_lt(
union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src0,
@@ -725,38 +810,6 @@ micro_lt(
dst->f[3] = src0->f[3] < src1->f[3] ? src2->f[3] : src3->f[3];
}
-#if 0
-static void
-micro_ilt(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1,
- const union tgsi_exec_channel *src2,
- const union tgsi_exec_channel *src3 )
-{
- dst->i[0] = src0->i[0] < src1->i[0] ? src2->i[0] : src3->i[0];
- dst->i[1] = src0->i[1] < src1->i[1] ? src2->i[1] : src3->i[1];
- dst->i[2] = src0->i[2] < src1->i[2] ? src2->i[2] : src3->i[2];
- dst->i[3] = src0->i[3] < src1->i[3] ? src2->i[3] : src3->i[3];
-}
-#endif
-
-#if 0
-static void
-micro_ult(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1,
- const union tgsi_exec_channel *src2,
- const union tgsi_exec_channel *src3 )
-{
- dst->u[0] = src0->u[0] < src1->u[0] ? src2->u[0] : src3->u[0];
- dst->u[1] = src0->u[1] < src1->u[1] ? src2->u[1] : src3->u[1];
- dst->u[2] = src0->u[2] < src1->u[2] ? src2->u[2] : src3->u[2];
- dst->u[3] = src0->u[3] < src1->u[3] ? src2->u[3] : src3->u[3];
-}
-#endif
-
static void
micro_max(
union tgsi_exec_channel *dst,
@@ -769,34 +822,6 @@ micro_max(
dst->f[3] = src0->f[3] > src1->f[3] ? src0->f[3] : src1->f[3];
}
-#if 0
-static void
-micro_imax(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->i[0] = src0->i[0] > src1->i[0] ? src0->i[0] : src1->i[0];
- dst->i[1] = src0->i[1] > src1->i[1] ? src0->i[1] : src1->i[1];
- dst->i[2] = src0->i[2] > src1->i[2] ? src0->i[2] : src1->i[2];
- dst->i[3] = src0->i[3] > src1->i[3] ? src0->i[3] : src1->i[3];
-}
-#endif
-
-#if 0
-static void
-micro_umax(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->u[0] = src0->u[0] > src1->u[0] ? src0->u[0] : src1->u[0];
- dst->u[1] = src0->u[1] > src1->u[1] ? src0->u[1] : src1->u[1];
- dst->u[2] = src0->u[2] > src1->u[2] ? src0->u[2] : src1->u[2];
- dst->u[3] = src0->u[3] > src1->u[3] ? src0->u[3] : src1->u[3];
-}
-#endif
-
static void
micro_min(
union tgsi_exec_channel *dst,
@@ -809,48 +834,6 @@ micro_min(
dst->f[3] = src0->f[3] < src1->f[3] ? src0->f[3] : src1->f[3];
}
-#if 0
-static void
-micro_imin(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->i[0] = src0->i[0] < src1->i[0] ? src0->i[0] : src1->i[0];
- dst->i[1] = src0->i[1] < src1->i[1] ? src0->i[1] : src1->i[1];
- dst->i[2] = src0->i[2] < src1->i[2] ? src0->i[2] : src1->i[2];
- dst->i[3] = src0->i[3] < src1->i[3] ? src0->i[3] : src1->i[3];
-}
-#endif
-
-#if 0
-static void
-micro_umin(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->u[0] = src0->u[0] < src1->u[0] ? src0->u[0] : src1->u[0];
- dst->u[1] = src0->u[1] < src1->u[1] ? src0->u[1] : src1->u[1];
- dst->u[2] = src0->u[2] < src1->u[2] ? src0->u[2] : src1->u[2];
- dst->u[3] = src0->u[3] < src1->u[3] ? src0->u[3] : src1->u[3];
-}
-#endif
-
-#if 0
-static void
-micro_umod(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->u[0] = src0->u[0] % src1->u[0];
- dst->u[1] = src0->u[1] % src1->u[1];
- dst->u[2] = src0->u[2] % src1->u[2];
- dst->u[3] = src0->u[3] % src1->u[3];
-}
-#endif
-
static void
micro_mul(
union tgsi_exec_channel *dst,
@@ -865,20 +848,6 @@ micro_mul(
#if 0
static void
-micro_imul(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->i[0] = src0->i[0] * src1->i[0];
- dst->i[1] = src0->i[1] * src1->i[1];
- dst->i[2] = src0->i[2] * src1->i[2];
- dst->i[3] = src0->i[3] * src1->i[3];
-}
-#endif
-
-#if 0
-static void
micro_imul64(
union tgsi_exec_channel *dst0,
union tgsi_exec_channel *dst1,
@@ -942,42 +911,6 @@ micro_neg(
dst->f[3] = -src->f[3];
}
-#if 0
-static void
-micro_ineg(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->i[0] = -src->i[0];
- dst->i[1] = -src->i[1];
- dst->i[2] = -src->i[2];
- dst->i[3] = -src->i[3];
-}
-#endif
-
-static void
-micro_not(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->u[0] = ~src->u[0];
- dst->u[1] = ~src->u[1];
- dst->u[2] = ~src->u[2];
- dst->u[3] = ~src->u[3];
-}
-
-static void
-micro_or(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->u[0] = src0->u[0] | src1->u[0];
- dst->u[1] = src0->u[1] | src1->u[1];
- dst->u[2] = src0->u[2] | src1->u[2];
- dst->u[3] = src0->u[3] | src1->u[3];
-}
-
static void
micro_pow(
union tgsi_exec_channel *dst,
@@ -998,88 +931,6 @@ micro_pow(
}
static void
-micro_rnd(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = floorf( src->f[0] + 0.5f );
- dst->f[1] = floorf( src->f[1] + 0.5f );
- dst->f[2] = floorf( src->f[2] + 0.5f );
- dst->f[3] = floorf( src->f[3] + 0.5f );
-}
-
-static void
-micro_sgn(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = src->f[0] < 0.0f ? -1.0f : src->f[0] > 0.0f ? 1.0f : 0.0f;
- dst->f[1] = src->f[1] < 0.0f ? -1.0f : src->f[1] > 0.0f ? 1.0f : 0.0f;
- dst->f[2] = src->f[2] < 0.0f ? -1.0f : src->f[2] > 0.0f ? 1.0f : 0.0f;
- dst->f[3] = src->f[3] < 0.0f ? -1.0f : src->f[3] > 0.0f ? 1.0f : 0.0f;
-}
-
-static void
-micro_shl(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->i[0] = src0->i[0] << src1->i[0];
- dst->i[1] = src0->i[1] << src1->i[1];
- dst->i[2] = src0->i[2] << src1->i[2];
- dst->i[3] = src0->i[3] << src1->i[3];
-}
-
-static void
-micro_ishr(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->i[0] = src0->i[0] >> src1->i[0];
- dst->i[1] = src0->i[1] >> src1->i[1];
- dst->i[2] = src0->i[2] >> src1->i[2];
- dst->i[3] = src0->i[3] >> src1->i[3];
-}
-
-static void
-micro_trunc(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0 )
-{
- dst->f[0] = (float) (int) src0->f[0];
- dst->f[1] = (float) (int) src0->f[1];
- dst->f[2] = (float) (int) src0->f[2];
- dst->f[3] = (float) (int) src0->f[3];
-}
-
-#if 0
-static void
-micro_ushr(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->u[0] = src0->u[0] >> src1->u[0];
- dst->u[1] = src0->u[1] >> src1->u[1];
- dst->u[2] = src0->u[2] >> src1->u[2];
- dst->u[3] = src0->u[3] >> src1->u[3];
-}
-#endif
-
-static void
-micro_sin(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = sinf( src->f[0] );
- dst->f[1] = sinf( src->f[1] );
- dst->f[2] = sinf( src->f[2] );
- dst->f[3] = sinf( src->f[3] );
-}
-
-static void
micro_sqrt( union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src )
{
@@ -1101,31 +952,6 @@ micro_sub(
dst->f[3] = src0->f[3] - src1->f[3];
}
-#if 0
-static void
-micro_u2f(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src )
-{
- dst->f[0] = (float) src->u[0];
- dst->f[1] = (float) src->u[1];
- dst->f[2] = (float) src->u[2];
- dst->f[3] = (float) src->u[3];
-}
-#endif
-
-static void
-micro_xor(
- union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1 )
-{
- dst->u[0] = src0->u[0] ^ src1->u[0];
- dst->u[1] = src0->u[1] ^ src1->u[1];
- dst->u[2] = src0->u[2] ^ src1->u[2];
- dst->u[3] = src0->u[3] ^ src1->u[3];
-}
-
static void
fetch_src_file_channel(
const struct tgsi_exec_machine *mach,
@@ -1215,20 +1041,28 @@ fetch_src_file_channel(
default:
assert( 0 );
+ chan->u[0] = 0;
+ chan->u[1] = 0;
+ chan->u[2] = 0;
+ chan->u[3] = 0;
}
break;
default:
assert( 0 );
+ chan->u[0] = 0;
+ chan->u[1] = 0;
+ chan->u[2] = 0;
+ chan->u[3] = 0;
}
}
static void
-fetch_source(
- const struct tgsi_exec_machine *mach,
- union tgsi_exec_channel *chan,
- const struct tgsi_full_src_register *reg,
- const uint chan_index )
+fetch_source(const struct tgsi_exec_machine *mach,
+ union tgsi_exec_channel *chan,
+ const struct tgsi_full_src_register *reg,
+ const uint chan_index,
+ enum tgsi_exec_datatype src_datatype)
{
union tgsi_exec_channel index;
uint swizzle;
@@ -1277,10 +1111,10 @@ fetch_source(
&indir_index );
/* add value of address register to the offset */
- index.i[0] += (int) indir_index.f[0];
- index.i[1] += (int) indir_index.f[1];
- index.i[2] += (int) indir_index.f[2];
- index.i[3] += (int) indir_index.f[3];
+ index.i[0] += indir_index.i[0];
+ index.i[1] += indir_index.i[1];
+ index.i[2] += indir_index.i[2];
+ index.i[3] += indir_index.i[3];
/* for disabled execution channels, zero-out the index to
* avoid using a potential garbage value.
@@ -1357,10 +1191,10 @@ fetch_source(
&index2,
&indir_index );
- index.i[0] += (int) indir_index.f[0];
- index.i[1] += (int) indir_index.f[1];
- index.i[2] += (int) indir_index.f[2];
- index.i[3] += (int) indir_index.f[3];
+ index.i[0] += indir_index.i[0];
+ index.i[1] += indir_index.i[1];
+ index.i[2] += indir_index.i[2];
+ index.i[3] += indir_index.i[3];
/* for disabled execution channels, zero-out the index to
* avoid using a potential garbage value.
@@ -1385,32 +1219,30 @@ fetch_source(
&index,
chan );
- switch (tgsi_util_get_full_src_register_sign_mode( reg, chan_index )) {
- case TGSI_UTIL_SIGN_CLEAR:
- micro_abs( chan, chan );
- break;
-
- case TGSI_UTIL_SIGN_SET:
- micro_abs( chan, chan );
- micro_neg( chan, chan );
- break;
-
- case TGSI_UTIL_SIGN_TOGGLE:
- micro_neg( chan, chan );
- break;
+ if (reg->Register.Absolute) {
+ if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
+ micro_abs(chan, chan);
+ } else {
+ micro_iabs(chan, chan);
+ }
+ }
- case TGSI_UTIL_SIGN_KEEP:
- break;
+ if (reg->Register.Negate) {
+ if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
+ micro_neg(chan, chan);
+ } else {
+ micro_ineg(chan, chan);
+ }
}
}
static void
-store_dest(
- struct tgsi_exec_machine *mach,
- const union tgsi_exec_channel *chan,
- const struct tgsi_full_dst_register *reg,
- const struct tgsi_full_instruction *inst,
- uint chan_index )
+store_dest(struct tgsi_exec_machine *mach,
+ const union tgsi_exec_channel *chan,
+ const struct tgsi_full_dst_register *reg,
+ const struct tgsi_full_instruction *inst,
+ uint chan_index,
+ enum tgsi_exec_datatype dst_datatype)
{
uint i;
union tgsi_exec_channel null;
@@ -1419,9 +1251,9 @@ store_dest(
int offset = 0; /* indirection offset */
int index;
-#ifdef DEBUG
- check_inf_or_nan(chan);
-#endif
+ if (dst_datatype == TGSI_EXEC_DATA_FLOAT) {
+ CHECK_INF_OR_NAN(chan);
+ }
/* There is an extra source register that indirectly subscripts
* a register file. The direct index now becomes an offset
@@ -1456,7 +1288,7 @@ store_dest(
&indir_index );
/* save indirection offset */
- offset = (int) indir_index.f[0];
+ offset = indir_index.i[0];
}
switch (reg->Register.File) {
@@ -1468,6 +1300,15 @@ store_dest(
index = mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
+ reg->Register.Index;
dst = &mach->Outputs[offset + index].xyzw[chan_index];
+#if 0
+ if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) {
+ fprintf(stderr, "STORING OUT[%d] mask(%d), = (", offset + index, execmask);
+ for (i = 0; i < QUAD_SIZE; i++)
+ if (execmask & (1 << i))
+ fprintf(stderr, "%f, ", chan->f[i]);
+ fprintf(stderr, ")\n");
+ }
+#endif
break;
case TGSI_FILE_TEMPORARY:
@@ -1577,10 +1418,10 @@ store_dest(
}
#define FETCH(VAL,INDEX,CHAN)\
- fetch_source (mach, VAL, &inst->Src[INDEX], CHAN)
+ fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_FLOAT)
#define STORE(VAL,INDEX,CHAN)\
- store_dest (mach, VAL, &inst->Dst[INDEX], inst, CHAN )
+ store_dest(mach, VAL, &inst->Dst[INDEX], inst, CHAN, TGSI_EXEC_DATA_FLOAT)
/**
@@ -1638,6 +1479,35 @@ exec_kilp(struct tgsi_exec_machine *mach,
mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask;
}
+static void
+emit_vertex(struct tgsi_exec_machine *mach)
+{
+ /* FIXME: check for exec mask correctly
+ unsigned i;
+ for (i = 0; i < QUAD_SIZE; ++i) {
+ if ((mach->ExecMask & (1 << i)))
+ */
+ if (mach->ExecMask) {
+ mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += mach->NumOutputs;
+ mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
+ }
+}
+
+static void
+emit_primitive(struct tgsi_exec_machine *mach)
+{
+ unsigned *prim_count = &mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];
+ /* FIXME: check for exec mask correctly
+ unsigned i;
+ for (i = 0; i < QUAD_SIZE; ++i) {
+ if ((mach->ExecMask & (1 << i)))
+ */
+ if (mach->ExecMask) {
+ ++(*prim_count);
+ debug_assert((*prim_count * mach->NumOutputs) < mach->MaxGeometryShaderOutputs);
+ mach->Primitives[*prim_count] = 0;
+ }
+}
/*
* Fetch a four texture samples using STR texture coordinates.
@@ -1647,7 +1517,8 @@ fetch_texel( struct tgsi_sampler *sampler,
const union tgsi_exec_channel *s,
const union tgsi_exec_channel *t,
const union tgsi_exec_channel *p,
- float lodbias, /* XXX should be float[4] */
+ const union tgsi_exec_channel *c0,
+ enum tgsi_sampler_control control,
union tgsi_exec_channel *r,
union tgsi_exec_channel *g,
union tgsi_exec_channel *b,
@@ -1656,7 +1527,7 @@ fetch_texel( struct tgsi_sampler *sampler,
uint j;
float rgba[NUM_CHANNELS][QUAD_SIZE];
- sampler->get_samples(sampler, s->f, t->f, p->f, lodbias, rgba);
+ sampler->get_samples(sampler, s->f, t->f, p->f, c0->f, control, rgba);
for (j = 0; j < 4; j++) {
r->f[j] = rgba[0][j];
@@ -1667,102 +1538,95 @@ fetch_texel( struct tgsi_sampler *sampler,
}
+#define TEX_MODIFIER_NONE 0
+#define TEX_MODIFIER_PROJECTED 1
+#define TEX_MODIFIER_LOD_BIAS 2
+#define TEX_MODIFIER_EXPLICIT_LOD 3
+
+
static void
exec_tex(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst,
- boolean biasLod,
- boolean projected)
+ uint modifier)
{
const uint unit = inst->Src[1].Register.Index;
union tgsi_exec_channel r[4];
+ const union tgsi_exec_channel *lod = &ZeroVec;
+ enum tgsi_sampler_control control;
uint chan_index;
- float lodBias;
- /* debug_printf("Sampler %u unit %u\n", sampler, unit); */
+ if (modifier != TEX_MODIFIER_NONE) {
+ FETCH(&r[3], 0, CHAN_W);
+ if (modifier != TEX_MODIFIER_PROJECTED) {
+ lod = &r[3];
+ }
+ }
+
+ if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
+ control = tgsi_sampler_lod_explicit;
+ } else {
+ control = tgsi_sampler_lod_bias;
+ }
switch (inst->Texture.Texture) {
case TGSI_TEXTURE_1D:
case TGSI_TEXTURE_SHADOW1D:
-
FETCH(&r[0], 0, CHAN_X);
- if (projected) {
- FETCH(&r[1], 0, CHAN_W);
- micro_div( &r[0], &r[0], &r[1] );
- }
-
- if (biasLod) {
- FETCH(&r[1], 0, CHAN_W);
- lodBias = r[2].f[0];
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
}
- else
- lodBias = 0.0;
fetch_texel(mach->Samplers[unit],
- &r[0], &ZeroVec, &ZeroVec, lodBias, /* S, T, P, BIAS */
- &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+ &r[0], &ZeroVec, &ZeroVec, lod, /* S, T, P, LOD */
+ control,
+ &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
case TGSI_TEXTURE_SHADOW2D:
case TGSI_TEXTURE_SHADOWRECT:
-
FETCH(&r[0], 0, CHAN_X);
FETCH(&r[1], 0, CHAN_Y);
FETCH(&r[2], 0, CHAN_Z);
- if (projected) {
- FETCH(&r[3], 0, CHAN_W);
- micro_div( &r[0], &r[0], &r[3] );
- micro_div( &r[1], &r[1], &r[3] );
- micro_div( &r[2], &r[2], &r[3] );
- }
-
- if (biasLod) {
- FETCH(&r[3], 0, CHAN_W);
- lodBias = r[3].f[0];
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ micro_div(&r[1], &r[1], &r[3]);
+ micro_div(&r[2], &r[2], &r[3]);
}
- else
- lodBias = 0.0;
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], lodBias, /* inputs */
+ &r[0], &r[1], &r[2], lod, /* S, T, P, LOD */
+ control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
-
FETCH(&r[0], 0, CHAN_X);
FETCH(&r[1], 0, CHAN_Y);
FETCH(&r[2], 0, CHAN_Z);
- if (projected) {
- FETCH(&r[3], 0, CHAN_W);
- micro_div( &r[0], &r[0], &r[3] );
- micro_div( &r[1], &r[1], &r[3] );
- micro_div( &r[2], &r[2], &r[3] );
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ micro_div(&r[1], &r[1], &r[3]);
+ micro_div(&r[2], &r[2], &r[3]);
}
- if (biasLod) {
- FETCH(&r[3], 0, CHAN_W);
- lodBias = r[3].f[0];
- }
- else
- lodBias = 0.0;
-
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], lodBias,
+ &r[0], &r[1], &r[2], lod,
+ control,
&r[0], &r[1], &r[2], &r[3]);
break;
default:
- assert (0);
+ assert(0);
}
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[chan_index], 0, chan_index );
+ FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
+ STORE(&r[chan_index], 0, chan_index);
}
}
@@ -1785,8 +1649,9 @@ exec_txd(struct tgsi_exec_machine *mach,
FETCH(&r[0], 0, CHAN_X);
fetch_texel(mach->Samplers[unit],
- &r[0], &ZeroVec, &ZeroVec, 0.0f, /* S, T, P, BIAS */
- &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+ &r[0], &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, BIAS */
+ tgsi_sampler_lod_bias,
+ &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
case TGSI_TEXTURE_2D:
@@ -1799,8 +1664,9 @@ exec_txd(struct tgsi_exec_machine *mach,
FETCH(&r[2], 0, CHAN_Z);
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], 0.0f, /* inputs */
- &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ &r[0], &r[1], &r[2], &ZeroVec, /* inputs */
+ tgsi_sampler_lod_bias,
+ &r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
case TGSI_TEXTURE_3D:
@@ -1811,7 +1677,8 @@ exec_txd(struct tgsi_exec_machine *mach,
FETCH(&r[2], 0, CHAN_Z);
fetch_texel(mach->Samplers[unit],
- &r[0], &r[1], &r[2], 0.0f,
+ &r[0], &r[1], &r[2], &ZeroVec,
+ tgsi_sampler_lod_bias,
&r[0], &r[1], &r[2], &r[3]);
break;
@@ -1908,7 +1775,7 @@ exec_declaration(struct tgsi_exec_machine *mach,
if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) {
assert(decl->Semantic.Index == 0);
assert(first == last);
- assert(mask = TGSI_WRITEMASK_XYZW);
+ assert(mask == TGSI_WRITEMASK_XYZW);
mach->Inputs[first] = mach->QuadPos;
} else if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) {
@@ -1954,6 +1821,585 @@ exec_declaration(struct tgsi_exec_machine *mach,
}
}
+typedef void (* micro_op)(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src);
+
+static void
+exec_scalar_unary(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst,
+ micro_op op,
+ enum tgsi_exec_datatype dst_datatype,
+ enum tgsi_exec_datatype src_datatype)
+{
+ unsigned int chan;
+ union tgsi_exec_channel src;
+ union tgsi_exec_channel dst;
+
+ fetch_source(mach, &src, &inst->Src[0], CHAN_X, src_datatype);
+ op(&dst, &src);
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &dst, &inst->Dst[0], inst, chan, dst_datatype);
+ }
+ }
+}
+
+static void
+exec_vector_unary(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst,
+ micro_op op,
+ enum tgsi_exec_datatype dst_datatype,
+ enum tgsi_exec_datatype src_datatype)
+{
+ unsigned int chan;
+ struct tgsi_exec_vector dst;
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ union tgsi_exec_channel src;
+
+ fetch_source(mach, &src, &inst->Src[0], chan, src_datatype);
+ op(&dst.xyzw[chan], &src);
+ }
+ }
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
+ }
+ }
+}
+
+static void
+exec_vector_binary(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst,
+ micro_op op,
+ enum tgsi_exec_datatype dst_datatype,
+ enum tgsi_exec_datatype src_datatype)
+{
+ unsigned int chan;
+ struct tgsi_exec_vector dst;
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ union tgsi_exec_channel src[2];
+
+ fetch_source(mach, &src[0], &inst->Src[0], chan, src_datatype);
+ fetch_source(mach, &src[1], &inst->Src[1], chan, src_datatype);
+ op(&dst.xyzw[chan], src);
+ }
+ }
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
+ }
+ }
+}
+
+static void
+exec_vector_trinary(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst,
+ micro_op op,
+ enum tgsi_exec_datatype dst_datatype,
+ enum tgsi_exec_datatype src_datatype)
+{
+ unsigned int chan;
+ struct tgsi_exec_vector dst;
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ union tgsi_exec_channel src[3];
+
+ fetch_source(mach, &src[0], &inst->Src[0], chan, src_datatype);
+ fetch_source(mach, &src[1], &inst->Src[1], chan, src_datatype);
+ fetch_source(mach, &src[2], &inst->Src[2], chan, src_datatype);
+ op(&dst.xyzw[chan], src);
+ }
+ }
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan, dst_datatype);
+ }
+ }
+}
+
+static void
+exec_dp3(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ unsigned int chan;
+ union tgsi_exec_channel arg[3];
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ micro_mul(&arg[2], &arg[0], &arg[1]);
+
+ for (chan = CHAN_Y; chan <= CHAN_Z; chan++) {
+ fetch_source(mach, &arg[0], &inst->Src[0], chan, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], chan, TGSI_EXEC_DATA_FLOAT);
+ micro_mad(&arg[2], arg);
+ }
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+}
+
+static void
+exec_dp4(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ unsigned int chan;
+ union tgsi_exec_channel arg[3];
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ micro_mul(&arg[2], &arg[0], &arg[1]);
+
+ for (chan = CHAN_Y; chan <= CHAN_W; chan++) {
+ fetch_source(mach, &arg[0], &inst->Src[0], chan, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], chan, TGSI_EXEC_DATA_FLOAT);
+ micro_mad(&arg[2], arg);
+ }
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+}
+
+static void
+exec_dp2a(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ unsigned int chan;
+ union tgsi_exec_channel arg[3];
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ micro_mul(&arg[2], &arg[0], &arg[1]);
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+ micro_mad(&arg[0], arg);
+
+ fetch_source(mach, &arg[1], &inst->Src[2], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ micro_add(&arg[0], &arg[0], &arg[1]);
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &arg[0], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+}
+
+static void
+exec_dph(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ unsigned int chan;
+ union tgsi_exec_channel arg[3];
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ micro_mul(&arg[2], &arg[0], &arg[1]);
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+ micro_mad(&arg[2], arg);
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_Z, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_FLOAT);
+ micro_mad(&arg[0], arg);
+
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_FLOAT);
+ micro_add(&arg[0], &arg[0], &arg[1]);
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &arg[0], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+}
+
+static void
+exec_dp2(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ unsigned int chan;
+ union tgsi_exec_channel arg[3];
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ micro_mul(&arg[2], &arg[0], &arg[1]);
+
+ fetch_source(mach, &arg[0], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &arg[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+ micro_mad(&arg[2], arg);
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &arg[2], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+}
+
+static void
+exec_break(struct tgsi_exec_machine *mach)
+{
+ if (mach->BreakType == TGSI_EXEC_BREAK_INSIDE_LOOP) {
+ /* turn off loop channels for each enabled exec channel */
+ mach->LoopMask &= ~mach->ExecMask;
+ /* Todo: if mach->LoopMask == 0, jump to end of loop */
+ UPDATE_EXEC_MASK(mach);
+ } else {
+ assert(mach->BreakType == TGSI_EXEC_BREAK_INSIDE_SWITCH);
+
+ mach->Switch.mask = 0x0;
+
+ UPDATE_EXEC_MASK(mach);
+ }
+}
+
+static void
+exec_switch(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ assert(mach->SwitchStackTop < TGSI_EXEC_MAX_SWITCH_NESTING);
+ assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
+
+ mach->SwitchStack[mach->SwitchStackTop++] = mach->Switch;
+ fetch_source(mach, &mach->Switch.selector, &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_UINT);
+ mach->Switch.mask = 0x0;
+ mach->Switch.defaultMask = 0x0;
+
+ mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
+ mach->BreakType = TGSI_EXEC_BREAK_INSIDE_SWITCH;
+
+ UPDATE_EXEC_MASK(mach);
+}
+
+static void
+exec_case(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ uint prevMask = mach->SwitchStack[mach->SwitchStackTop - 1].mask;
+ union tgsi_exec_channel src;
+ uint mask = 0;
+
+ fetch_source(mach, &src, &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_UINT);
+
+ if (mach->Switch.selector.u[0] == src.u[0]) {
+ mask |= 0x1;
+ }
+ if (mach->Switch.selector.u[1] == src.u[1]) {
+ mask |= 0x2;
+ }
+ if (mach->Switch.selector.u[2] == src.u[2]) {
+ mask |= 0x4;
+ }
+ if (mach->Switch.selector.u[3] == src.u[3]) {
+ mask |= 0x8;
+ }
+
+ mach->Switch.defaultMask |= mask;
+
+ mach->Switch.mask |= mask & prevMask;
+
+ UPDATE_EXEC_MASK(mach);
+}
+
+static void
+exec_default(struct tgsi_exec_machine *mach)
+{
+ uint prevMask = mach->SwitchStack[mach->SwitchStackTop - 1].mask;
+
+ mach->Switch.mask |= ~mach->Switch.defaultMask & prevMask;
+
+ UPDATE_EXEC_MASK(mach);
+}
+
+static void
+exec_endswitch(struct tgsi_exec_machine *mach)
+{
+ mach->Switch = mach->SwitchStack[--mach->SwitchStackTop];
+ mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
+
+ UPDATE_EXEC_MASK(mach);
+}
+
+static void
+micro_i2f(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = (float)src->i[0];
+ dst->f[1] = (float)src->i[1];
+ dst->f[2] = (float)src->i[2];
+ dst->f[3] = (float)src->i[3];
+}
+
+static void
+micro_not(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = ~src->u[0];
+ dst->u[1] = ~src->u[1];
+ dst->u[2] = ~src->u[2];
+ dst->u[3] = ~src->u[3];
+}
+
+static void
+micro_shl(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] << src[1].u[0];
+ dst->u[1] = src[0].u[1] << src[1].u[1];
+ dst->u[2] = src[0].u[2] << src[1].u[2];
+ dst->u[3] = src[0].u[3] << src[1].u[3];
+}
+
+static void
+micro_and(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] & src[1].u[0];
+ dst->u[1] = src[0].u[1] & src[1].u[1];
+ dst->u[2] = src[0].u[2] & src[1].u[2];
+ dst->u[3] = src[0].u[3] & src[1].u[3];
+}
+
+static void
+micro_or(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] | src[1].u[0];
+ dst->u[1] = src[0].u[1] | src[1].u[1];
+ dst->u[2] = src[0].u[2] | src[1].u[2];
+ dst->u[3] = src[0].u[3] | src[1].u[3];
+}
+
+static void
+micro_xor(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] ^ src[1].u[0];
+ dst->u[1] = src[0].u[1] ^ src[1].u[1];
+ dst->u[2] = src[0].u[2] ^ src[1].u[2];
+ dst->u[3] = src[0].u[3] ^ src[1].u[3];
+}
+
+static void
+micro_f2i(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = (int)src->f[0];
+ dst->i[1] = (int)src->f[1];
+ dst->i[2] = (int)src->f[2];
+ dst->i[3] = (int)src->f[3];
+}
+
+static void
+micro_idiv(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = src[0].i[0] / src[1].i[0];
+ dst->i[1] = src[0].i[1] / src[1].i[1];
+ dst->i[2] = src[0].i[2] / src[1].i[2];
+ dst->i[3] = src[0].i[3] / src[1].i[3];
+}
+
+static void
+micro_imax(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = src[0].i[0] > src[1].i[0] ? src[0].i[0] : src[1].i[0];
+ dst->i[1] = src[0].i[1] > src[1].i[1] ? src[0].i[1] : src[1].i[1];
+ dst->i[2] = src[0].i[2] > src[1].i[2] ? src[0].i[2] : src[1].i[2];
+ dst->i[3] = src[0].i[3] > src[1].i[3] ? src[0].i[3] : src[1].i[3];
+}
+
+static void
+micro_imin(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = src[0].i[0] < src[1].i[0] ? src[0].i[0] : src[1].i[0];
+ dst->i[1] = src[0].i[1] < src[1].i[1] ? src[0].i[1] : src[1].i[1];
+ dst->i[2] = src[0].i[2] < src[1].i[2] ? src[0].i[2] : src[1].i[2];
+ dst->i[3] = src[0].i[3] < src[1].i[3] ? src[0].i[3] : src[1].i[3];
+}
+
+static void
+micro_isge(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = src[0].i[0] >= src[1].i[0] ? -1 : 0;
+ dst->i[1] = src[0].i[1] >= src[1].i[1] ? -1 : 0;
+ dst->i[2] = src[0].i[2] >= src[1].i[2] ? -1 : 0;
+ dst->i[3] = src[0].i[3] >= src[1].i[3] ? -1 : 0;
+}
+
+static void
+micro_ishr(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = src[0].i[0] >> src[1].i[0];
+ dst->i[1] = src[0].i[1] >> src[1].i[1];
+ dst->i[2] = src[0].i[2] >> src[1].i[2];
+ dst->i[3] = src[0].i[3] >> src[1].i[3];
+}
+
+static void
+micro_islt(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = src[0].i[0] < src[1].i[0] ? -1 : 0;
+ dst->i[1] = src[0].i[1] < src[1].i[1] ? -1 : 0;
+ dst->i[2] = src[0].i[2] < src[1].i[2] ? -1 : 0;
+ dst->i[3] = src[0].i[3] < src[1].i[3] ? -1 : 0;
+}
+
+static void
+micro_f2u(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = (uint)src->f[0];
+ dst->u[1] = (uint)src->f[1];
+ dst->u[2] = (uint)src->f[2];
+ dst->u[3] = (uint)src->f[3];
+}
+
+static void
+micro_u2f(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->f[0] = (float)src->u[0];
+ dst->f[1] = (float)src->u[1];
+ dst->f[2] = (float)src->u[2];
+ dst->f[3] = (float)src->u[3];
+}
+
+static void
+micro_uadd(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] + src[1].u[0];
+ dst->u[1] = src[0].u[1] + src[1].u[1];
+ dst->u[2] = src[0].u[2] + src[1].u[2];
+ dst->u[3] = src[0].u[3] + src[1].u[3];
+}
+
+static void
+micro_udiv(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] / src[1].u[0];
+ dst->u[1] = src[0].u[1] / src[1].u[1];
+ dst->u[2] = src[0].u[2] / src[1].u[2];
+ dst->u[3] = src[0].u[3] / src[1].u[3];
+}
+
+static void
+micro_umad(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] * src[1].u[0] + src[2].u[0];
+ dst->u[1] = src[0].u[1] * src[1].u[1] + src[2].u[1];
+ dst->u[2] = src[0].u[2] * src[1].u[2] + src[2].u[2];
+ dst->u[3] = src[0].u[3] * src[1].u[3] + src[2].u[3];
+}
+
+static void
+micro_umax(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] > src[1].u[0] ? src[0].u[0] : src[1].u[0];
+ dst->u[1] = src[0].u[1] > src[1].u[1] ? src[0].u[1] : src[1].u[1];
+ dst->u[2] = src[0].u[2] > src[1].u[2] ? src[0].u[2] : src[1].u[2];
+ dst->u[3] = src[0].u[3] > src[1].u[3] ? src[0].u[3] : src[1].u[3];
+}
+
+static void
+micro_umin(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] < src[1].u[0] ? src[0].u[0] : src[1].u[0];
+ dst->u[1] = src[0].u[1] < src[1].u[1] ? src[0].u[1] : src[1].u[1];
+ dst->u[2] = src[0].u[2] < src[1].u[2] ? src[0].u[2] : src[1].u[2];
+ dst->u[3] = src[0].u[3] < src[1].u[3] ? src[0].u[3] : src[1].u[3];
+}
+
+static void
+micro_umod(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] % src[1].u[0];
+ dst->u[1] = src[0].u[1] % src[1].u[1];
+ dst->u[2] = src[0].u[2] % src[1].u[2];
+ dst->u[3] = src[0].u[3] % src[1].u[3];
+}
+
+static void
+micro_umul(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] * src[1].u[0];
+ dst->u[1] = src[0].u[1] * src[1].u[1];
+ dst->u[2] = src[0].u[2] * src[1].u[2];
+ dst->u[3] = src[0].u[3] * src[1].u[3];
+}
+
+static void
+micro_useq(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] == src[1].u[0] ? ~0 : 0;
+ dst->u[1] = src[0].u[1] == src[1].u[1] ? ~0 : 0;
+ dst->u[2] = src[0].u[2] == src[1].u[2] ? ~0 : 0;
+ dst->u[3] = src[0].u[3] == src[1].u[3] ? ~0 : 0;
+}
+
+static void
+micro_usge(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] >= src[1].u[0] ? ~0 : 0;
+ dst->u[1] = src[0].u[1] >= src[1].u[1] ? ~0 : 0;
+ dst->u[2] = src[0].u[2] >= src[1].u[2] ? ~0 : 0;
+ dst->u[3] = src[0].u[3] >= src[1].u[3] ? ~0 : 0;
+}
+
+static void
+micro_ushr(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] >> src[1].u[0];
+ dst->u[1] = src[0].u[1] >> src[1].u[1];
+ dst->u[2] = src[0].u[2] >> src[1].u[2];
+ dst->u[3] = src[0].u[3] >> src[1].u[3];
+}
+
+static void
+micro_uslt(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] < src[1].u[0] ? ~0 : 0;
+ dst->u[1] = src[0].u[1] < src[1].u[1] ? ~0 : 0;
+ dst->u[2] = src[0].u[2] < src[1].u[2] ? ~0 : 0;
+ dst->u[3] = src[0].u[3] < src[1].u[3] ? ~0 : 0;
+}
+
+static void
+micro_usne(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u[0] = src[0].u[0] != src[1].u[0] ? ~0 : 0;
+ dst->u[1] = src[0].u[1] != src[1].u[1] ? ~0 : 0;
+ dst->u[2] = src[0].u[2] != src[1].u[2] ? ~0 : 0;
+ dst->u[3] = src[0].u[3] != src[1].u[3] ? ~0 : 0;
+}
+
static void
exec_instruction(
struct tgsi_exec_machine *mach,
@@ -1968,23 +2414,11 @@ exec_instruction(
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ARL:
- case TGSI_OPCODE_FLR:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_flr(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_arl, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_MOV:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH(&d[chan_index], 0, chan_index);
- }
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_mov, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_LIT:
@@ -2021,23 +2455,11 @@ exec_instruction(
break;
case TGSI_OPCODE_RCP:
- /* TGSI_OPCODE_RECIP */
- FETCH( &r[0], 0, CHAN_X );
- micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] );
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_scalar_unary(mach, inst, micro_rcp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_RSQ:
- /* TGSI_OPCODE_RECIPSQRT */
- FETCH( &r[0], 0, CHAN_X );
- micro_abs( &r[0], &r[0] );
- micro_sqrt( &r[0], &r[0] );
- micro_div( &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0] );
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_scalar_unary(mach, inst, micro_rsq, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_EXP:
@@ -2104,54 +2526,11 @@ exec_instruction(
break;
case TGSI_OPCODE_DP3:
- /* TGSI_OPCODE_DOT3 */
- FETCH( &r[0], 0, CHAN_X );
- FETCH( &r[1], 1, CHAN_X );
- micro_mul( &r[0], &r[0], &r[1] );
-
- FETCH( &r[1], 0, CHAN_Y );
- FETCH( &r[2], 1, CHAN_Y );
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FETCH( &r[1], 0, CHAN_Z );
- FETCH( &r[2], 1, CHAN_Z );
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_dp3(mach, inst);
break;
- case TGSI_OPCODE_DP4:
- /* TGSI_OPCODE_DOT4 */
- FETCH(&r[0], 0, CHAN_X);
- FETCH(&r[1], 1, CHAN_X);
-
- micro_mul( &r[0], &r[0], &r[1] );
-
- FETCH(&r[1], 0, CHAN_Y);
- FETCH(&r[2], 1, CHAN_Y);
-
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FETCH(&r[1], 0, CHAN_Z);
- FETCH(&r[2], 1, CHAN_Z);
-
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FETCH(&r[1], 0, CHAN_W);
- FETCH(&r[2], 1, CHAN_W);
-
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ case TGSI_OPCODE_DP4:
+ exec_dp4(mach, inst);
break;
case TGSI_OPCODE_DST:
@@ -2208,41 +2587,15 @@ exec_instruction(
break;
case TGSI_OPCODE_SLT:
- /* TGSI_OPCODE_SETLT */
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_lt(&d[chan_index], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_slt, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_SGE:
- /* TGSI_OPCODE_SETGE */
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_le(&d[chan_index], &r[1], &r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_sge, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_MAD:
- /* TGSI_OPCODE_MADD */
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_mul( &r[0], &r[0], &r[1] );
- FETCH( &r[1], 2, chan_index );
- micro_add(&d[chan_index], &r[0], &r[1]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_trinary(mach, inst, micro_mad, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_SUB:
@@ -2257,17 +2610,7 @@ exec_instruction(
break;
case TGSI_OPCODE_LRP:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH(&r[0], 0, chan_index);
- FETCH(&r[1], 1, chan_index);
- FETCH(&r[2], 2, chan_index);
- micro_sub( &r[1], &r[1], &r[2] );
- micro_mul( &r[0], &r[0], &r[1] );
- micro_add(&d[chan_index], &r[0], &r[2]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_trinary(mach, inst, micro_lrp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_CND:
@@ -2283,31 +2626,11 @@ exec_instruction(
break;
case TGSI_OPCODE_DP2A:
- FETCH( &r[0], 0, CHAN_X );
- FETCH( &r[1], 1, CHAN_X );
- micro_mul( &r[0], &r[0], &r[1] );
-
- FETCH( &r[1], 0, CHAN_Y );
- FETCH( &r[2], 1, CHAN_Y );
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FETCH( &r[2], 2, CHAN_X );
- micro_add( &r[0], &r[0], &r[2] );
-
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_dp2a(mach, inst);
break;
case TGSI_OPCODE_FRC:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_frc(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_frc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_CLAMP:
@@ -2323,33 +2646,20 @@ exec_instruction(
}
break;
+ case TGSI_OPCODE_FLR:
+ exec_vector_unary(mach, inst, micro_flr, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
+ break;
+
case TGSI_OPCODE_ROUND:
- case TGSI_OPCODE_ARR:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_rnd(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_rnd, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_EX2:
- FETCH(&r[0], 0, CHAN_X);
-
- micro_exp2( &r[0], &r[0] );
-
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_scalar_unary(mach, inst, micro_exp2, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_LG2:
- FETCH( &r[0], 0, CHAN_X );
- micro_lg2( &r[0], &r[0] );
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_scalar_unary(mach, inst, micro_lg2, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_POW:
@@ -2402,15 +2712,9 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_ABS:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH(&r[0], 0, chan_index);
- micro_abs(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
- break;
+ case TGSI_OPCODE_ABS:
+ exec_vector_unary(mach, inst, micro_abs, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
+ break;
case TGSI_OPCODE_RCC:
FETCH(&r[0], 0, CHAN_X);
@@ -2422,60 +2726,19 @@ exec_instruction(
break;
case TGSI_OPCODE_DPH:
- FETCH(&r[0], 0, CHAN_X);
- FETCH(&r[1], 1, CHAN_X);
-
- micro_mul( &r[0], &r[0], &r[1] );
-
- FETCH(&r[1], 0, CHAN_Y);
- FETCH(&r[2], 1, CHAN_Y);
-
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FETCH(&r[1], 0, CHAN_Z);
- FETCH(&r[2], 1, CHAN_Z);
-
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FETCH(&r[1], 1, CHAN_W);
-
- micro_add( &r[0], &r[0], &r[1] );
-
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_dph(mach, inst);
break;
case TGSI_OPCODE_COS:
- FETCH(&r[0], 0, CHAN_X);
-
- micro_cos( &r[0], &r[0] );
-
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_scalar_unary(mach, inst, micro_cos, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_DDX:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_ddx(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_ddx, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_DDY:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_ddy(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_ddy, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_KILP:
@@ -2552,14 +2815,7 @@ exec_instruction(
break;
case TGSI_OPCODE_SEQ:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_eq(&d[chan_index], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_seq, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_SFL:
@@ -2569,44 +2825,19 @@ exec_instruction(
break;
case TGSI_OPCODE_SGT:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_le(&d[chan_index], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_sgt, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_SIN:
- FETCH( &r[0], 0, CHAN_X );
- micro_sin( &r[0], &r[0] );
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_scalar_unary(mach, inst, micro_sin, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_SLE:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_le(&d[chan_index], &r[0], &r[1], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_sle, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_SNE:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_eq(&d[chan_index], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_sne, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_STR:
@@ -2619,14 +2850,14 @@ exec_instruction(
/* simple texture lookup */
/* src[0] = texcoord */
/* src[1] = sampler unit */
- exec_tex(mach, inst, FALSE, FALSE);
+ exec_tex(mach, inst, TEX_MODIFIER_NONE);
break;
case TGSI_OPCODE_TXB:
/* Texture lookup with lod bias */
/* src[0] = texcoord (src[0].w = LOD bias) */
/* src[1] = sampler unit */
- exec_tex(mach, inst, TRUE, FALSE);
+ exec_tex(mach, inst, TEX_MODIFIER_LOD_BIAS);
break;
case TGSI_OPCODE_TXD:
@@ -2642,14 +2873,14 @@ exec_instruction(
/* Texture lookup with explit LOD */
/* src[0] = texcoord (src[0].w = LOD) */
/* src[1] = sampler unit */
- exec_tex(mach, inst, TRUE, FALSE);
+ exec_tex(mach, inst, TEX_MODIFIER_EXPLICIT_LOD);
break;
case TGSI_OPCODE_TXP:
/* Texture lookup with projection */
/* src[0] = texcoord (src[0].w = projection) */
/* src[1] = sampler unit */
- exec_tex(mach, inst, FALSE, TRUE);
+ exec_tex(mach, inst, TEX_MODIFIER_PROJECTED);
break;
case TGSI_OPCODE_UP2H:
@@ -2711,6 +2942,10 @@ exec_instruction(
assert (0);
break;
+ case TGSI_OPCODE_ARR:
+ exec_vector_unary(mach, inst, micro_arr, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
+ break;
+
case TGSI_OPCODE_BRA:
assert (0);
break;
@@ -2730,6 +2965,8 @@ exec_instruction(
mach->CallStack[mach->CallStackTop].CondStackTop = mach->CondStackTop;
mach->CallStack[mach->CallStackTop].LoopStackTop = mach->LoopStackTop;
mach->CallStack[mach->CallStackTop].ContStackTop = mach->ContStackTop;
+ mach->CallStack[mach->CallStackTop].SwitchStackTop = mach->SwitchStackTop;
+ mach->CallStack[mach->CallStackTop].BreakStackTop = mach->BreakStackTop;
/* note that PC was already incremented above */
mach->CallStack[mach->CallStackTop].ReturnAddr = *pc;
@@ -2737,12 +2974,17 @@ exec_instruction(
/* Second, push the Cond, Loop, Cont, Func stacks */
assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
- mach->CondStack[mach->CondStackTop++] = mach->CondMask;
assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
- mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
- mach->ContStack[mach->ContStackTop++] = mach->ContMask;
+ assert(mach->SwitchStackTop < TGSI_EXEC_MAX_SWITCH_NESTING);
+ assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING);
+
+ mach->CondStack[mach->CondStackTop++] = mach->CondMask;
+ mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
+ mach->ContStack[mach->ContStackTop++] = mach->ContMask;
+ mach->SwitchStack[mach->SwitchStackTop++] = mach->Switch;
+ mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask;
/* Finally, jump to the subroutine */
@@ -2775,6 +3017,12 @@ exec_instruction(
mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop;
mach->ContMask = mach->ContStack[mach->ContStackTop];
+ mach->SwitchStackTop = mach->CallStack[mach->CallStackTop].SwitchStackTop;
+ mach->Switch = mach->SwitchStack[mach->SwitchStackTop];
+
+ mach->BreakStackTop = mach->CallStack[mach->CallStackTop].BreakStackTop;
+ mach->BreakType = mach->BreakStack[mach->BreakStackTop];
+
assert(mach->FuncStackTop > 0);
mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
@@ -2785,14 +3033,7 @@ exec_instruction(
break;
case TGSI_OPCODE_SSG:
- /* TGSI_OPCODE_SGN */
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_sgn(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_sgn, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_CMP:
@@ -2899,18 +3140,7 @@ exec_instruction(
break;
case TGSI_OPCODE_DP2:
- FETCH( &r[0], 0, CHAN_X );
- FETCH( &r[1], 1, CHAN_X );
- micro_mul( &r[0], &r[0], &r[1] );
-
- FETCH( &r[1], 0, CHAN_Y );
- FETCH( &r[2], 1, CHAN_Y );
- micro_mul( &r[1], &r[1], &r[2] );
- micro_add( &r[0], &r[0], &r[1] );
-
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- STORE( &r[0], 0, chan_index );
- }
+ exec_dp2(mach, inst);
break;
case TGSI_OPCODE_IF:
@@ -2976,87 +3206,31 @@ exec_instruction(
break;
case TGSI_OPCODE_CEIL:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_ceil(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_ceil, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_I2F:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_i2f(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_i2f, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_INT);
break;
case TGSI_OPCODE_NOT:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_not(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_not, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
break;
case TGSI_OPCODE_TRUNC:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- micro_trunc(&d[chan_index], &r[0]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_unary(mach, inst, micro_trunc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_SHL:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_shl(&d[chan_index], &r[0], &r[1]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
- break;
-
- case TGSI_OPCODE_SHR:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_ishr(&d[chan_index], &r[0], &r[1]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_shl, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
break;
case TGSI_OPCODE_AND:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_and(&d[chan_index], &r[0], &r[1]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_and, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
break;
case TGSI_OPCODE_OR:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_or(&d[chan_index], &r[0], &r[1]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_or, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
break;
case TGSI_OPCODE_MOD:
@@ -3064,14 +3238,7 @@ exec_instruction(
break;
case TGSI_OPCODE_XOR:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- FETCH( &r[1], 1, chan_index );
- micro_xor(&d[chan_index], &r[0], &r[1]);
- }
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- STORE(&d[chan_index], 0, chan_index);
- }
+ exec_vector_binary(mach, inst, micro_xor, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
break;
case TGSI_OPCODE_SAD:
@@ -3087,13 +3254,11 @@ exec_instruction(
break;
case TGSI_OPCODE_EMIT:
- mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16;
- mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
+ emit_vertex(mach);
break;
case TGSI_OPCODE_ENDPRIM:
- mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++;
- mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
+ emit_primitive(mach);
break;
case TGSI_OPCODE_BGNFOR:
@@ -3122,11 +3287,15 @@ exec_instruction(
case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */
assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
- mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
- mach->ContStack[mach->ContStackTop++] = mach->ContMask;
assert(mach->LoopLabelStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+ assert(mach->BreakStackTop < TGSI_EXEC_MAX_BREAK_STACK);
+
+ mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
+ mach->ContStack[mach->ContStackTop++] = mach->ContMask;
mach->LoopLabelStack[mach->LoopLabelStackTop++] = *pc - 1;
+ mach->BreakStack[mach->BreakStackTop++] = mach->BreakType;
+ mach->BreakType = TGSI_EXEC_BREAK_INSIDE_LOOP;
break;
case TGSI_OPCODE_ENDFOR:
@@ -3173,6 +3342,8 @@ exec_instruction(
--mach->LoopLabelStackTop;
assert(mach->LoopCounterStackTop > 0);
--mach->LoopCounterStackTop;
+
+ mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
}
UPDATE_EXEC_MASK(mach);
break;
@@ -3196,15 +3367,14 @@ exec_instruction(
mach->ContMask = mach->ContStack[--mach->ContStackTop];
assert(mach->LoopLabelStackTop > 0);
--mach->LoopLabelStackTop;
+
+ mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
}
UPDATE_EXEC_MASK(mach);
break;
case TGSI_OPCODE_BRK:
- /* turn off loop channels for each enabled exec channel */
- mach->LoopMask &= ~mach->ExecMask;
- /* Todo: if mach->LoopMask == 0, jump to end of loop */
- UPDATE_EXEC_MASK(mach);
+ exec_break(mach);
break;
case TGSI_OPCODE_CONT:
@@ -3235,6 +3405,12 @@ exec_instruction(
mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop;
mach->ContMask = mach->ContStack[mach->ContStackTop];
+ mach->SwitchStackTop = mach->CallStack[mach->CallStackTop].SwitchStackTop;
+ mach->Switch = mach->SwitchStack[mach->SwitchStackTop];
+
+ mach->BreakStackTop = mach->CallStack[mach->CallStackTop].BreakStackTop;
+ mach->BreakType = mach->BreakStack[mach->BreakStackTop];
+
assert(mach->FuncStackTop > 0);
mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
@@ -3265,11 +3441,116 @@ exec_instruction(
UPDATE_EXEC_MASK(mach);
break;
+ case TGSI_OPCODE_F2I:
+ exec_vector_unary(mach, inst, micro_f2i, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
+ break;
+
+ case TGSI_OPCODE_IDIV:
+ exec_vector_binary(mach, inst, micro_idiv, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_IMAX:
+ exec_vector_binary(mach, inst, micro_imax, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_IMIN:
+ exec_vector_binary(mach, inst, micro_imin, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_INEG:
+ exec_vector_unary(mach, inst, micro_ineg, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_ISGE:
+ exec_vector_binary(mach, inst, micro_isge, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_ISHR:
+ exec_vector_binary(mach, inst, micro_ishr, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_ISLT:
+ exec_vector_binary(mach, inst, micro_islt, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_F2U:
+ exec_vector_unary(mach, inst, micro_f2u, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_FLOAT);
+ break;
+
+ case TGSI_OPCODE_U2F:
+ exec_vector_unary(mach, inst, micro_u2f, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_UADD:
+ exec_vector_binary(mach, inst, micro_uadd, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_UDIV:
+ exec_vector_binary(mach, inst, micro_udiv, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_UMAD:
+ exec_vector_trinary(mach, inst, micro_umad, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_UMAX:
+ exec_vector_binary(mach, inst, micro_umax, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_UMIN:
+ exec_vector_binary(mach, inst, micro_umin, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_UMOD:
+ exec_vector_binary(mach, inst, micro_umod, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_UMUL:
+ exec_vector_binary(mach, inst, micro_umul, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_USEQ:
+ exec_vector_binary(mach, inst, micro_useq, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_USGE:
+ exec_vector_binary(mach, inst, micro_usge, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_USHR:
+ exec_vector_binary(mach, inst, micro_ushr, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_USLT:
+ exec_vector_binary(mach, inst, micro_uslt, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_USNE:
+ exec_vector_binary(mach, inst, micro_usne, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_SWITCH:
+ exec_switch(mach, inst);
+ break;
+
+ case TGSI_OPCODE_CASE:
+ exec_case(mach, inst);
+ break;
+
+ case TGSI_OPCODE_DEFAULT:
+ exec_default(mach);
+ break;
+
+ case TGSI_OPCODE_ENDSWITCH:
+ exec_endswitch(mach);
+ break;
+
default:
assert( 0 );
}
}
+
#define DEBUG_EXECUTION 0
@@ -3289,9 +3570,13 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
mach->FuncMask = 0xf;
mach->ExecMask = 0xf;
+ mach->Switch.mask = 0xf;
+
assert(mach->CondStackTop == 0);
assert(mach->LoopStackTop == 0);
assert(mach->ContStackTop == 0);
+ assert(mach->SwitchStackTop == 0);
+ assert(mach->BreakStackTop == 0);
assert(mach->CallStackTop == 0);
mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] = 0;
@@ -3348,11 +3633,11 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
if (j > 0) {
debug_printf(" ");
}
- debug_printf("(%6f, %6f, %6f, %6f)\n",
- temps[i].xyzw[0].f[j],
- temps[i].xyzw[1].f[j],
- temps[i].xyzw[2].f[j],
- temps[i].xyzw[3].f[j]);
+ debug_printf("(%6f %u, %6f %u, %6f %u, %6f %u)\n",
+ temps[i].xyzw[0].f[j], temps[i].xyzw[0].u[j],
+ temps[i].xyzw[1].f[j], temps[i].xyzw[1].u[j],
+ temps[i].xyzw[2].f[j], temps[i].xyzw[2].u[j],
+ temps[i].xyzw[3].f[j], temps[i].xyzw[3].u[j]);
}
}
}
@@ -3366,11 +3651,11 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
if (j > 0) {
debug_printf(" ");
}
- debug_printf("{%6f, %6f, %6f, %6f}\n",
- outputs[i].xyzw[0].f[j],
- outputs[i].xyzw[1].f[j],
- outputs[i].xyzw[2].f[j],
- outputs[i].xyzw[3].f[j]);
+ debug_printf("(%6f %u, %6f %u, %6f %u, %6f %u)\n",
+ outputs[i].xyzw[0].f[j], outputs[i].xyzw[0].u[j],
+ outputs[i].xyzw[1].f[j], outputs[i].xyzw[1].u[j],
+ outputs[i].xyzw[2].f[j], outputs[i].xyzw[2].u[j],
+ outputs[i].xyzw[3].f[j], outputs[i].xyzw[3].u[j]);
}
}
}
@@ -3392,6 +3677,8 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
assert(mach->CondStackTop == 0);
assert(mach->LoopStackTop == 0);
assert(mach->ContStackTop == 0);
+ assert(mach->SwitchStackTop == 0);
+ assert(mach->BreakStackTop == 0);
assert(mach->CallStackTop == 0);
return ~mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0];
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index fd94c1bc44..59e3b445cc 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -2,6 +2,7 @@
*
* Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2009-2010 VMware, Inc. All rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -35,11 +36,13 @@
extern "C" {
#endif
+
#define MAX_LABELS (4 * 1024) /**< basically, max instructions */
#define NUM_CHANNELS 4 /* R,G,B,A */
#define QUAD_SIZE 4 /* 4 pixel/quad */
+
/**
* Registers may be treated as float, signed int or unsigned int.
*/
@@ -69,6 +72,11 @@ struct tgsi_interp_coef
float dady[NUM_CHANNELS];
};
+enum tgsi_sampler_control {
+ tgsi_sampler_lod_bias,
+ tgsi_sampler_lod_explicit
+};
+
/**
* Information for sampling textures, which must be implemented
* by code outside the TGSI executor.
@@ -80,7 +88,8 @@ struct tgsi_sampler
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- float lodbias,
+ const float c0[QUAD_SIZE],
+ enum tgsi_sampler_control control,
float rgba[NUM_CHANNELS][QUAD_SIZE]);
};
@@ -179,6 +188,7 @@ struct tgsi_exec_labels
#define TGSI_EXEC_MAX_COND_NESTING 32
#define TGSI_EXEC_MAX_LOOP_NESTING 32
+#define TGSI_EXEC_MAX_SWITCH_NESTING 32
#define TGSI_EXEC_MAX_CALL_NESTING 32
/* The maximum number of input attributes per vertex. For 2D
@@ -191,6 +201,14 @@ struct tgsi_exec_labels
*/
#define TGSI_EXEC_MAX_CONST_BUFFER 4096
+/* The maximum number of vertices per primitive */
+#define TGSI_MAX_PRIM_VERTICES 6
+
+/* The maximum number of primitives to be generated */
+#define TGSI_MAX_PRIMITIVES 64
+
+/* The maximum total number of vertices */
+#define TGSI_MAX_TOTAL_VERTICES (TGSI_MAX_PRIM_VERTICES * TGSI_MAX_PRIMITIVES * PIPE_MAX_ATTRIBS)
/** function call/activation record */
struct tgsi_call_record
@@ -198,10 +216,29 @@ struct tgsi_call_record
uint CondStackTop;
uint LoopStackTop;
uint ContStackTop;
+ int SwitchStackTop;
+ int BreakStackTop;
uint ReturnAddr;
};
+/* Switch-case block state. */
+struct tgsi_switch_record {
+ uint mask; /**< execution mask */
+ union tgsi_exec_channel selector; /**< a value case statements are compared to */
+ uint defaultMask; /**< non-execute mask for default case */
+};
+
+
+enum tgsi_break_type {
+ TGSI_EXEC_BREAK_INSIDE_LOOP,
+ TGSI_EXEC_BREAK_INSIDE_SWITCH
+};
+
+
+#define TGSI_EXEC_MAX_BREAK_STACK (TGSI_EXEC_MAX_LOOP_NESTING + TGSI_EXEC_MAX_SWITCH_NESTING)
+
+
/**
* Run-time virtual machine state for executing TGSI shader.
*/
@@ -214,8 +251,8 @@ struct tgsi_exec_machine
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
- struct tgsi_exec_vector Inputs[PIPE_MAX_ATTRIBS];
- struct tgsi_exec_vector Outputs[PIPE_MAX_ATTRIBS];
+ struct tgsi_exec_vector Inputs[TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS];
+ struct tgsi_exec_vector Outputs[TGSI_MAX_TOTAL_VERTICES];
struct tgsi_exec_vector *Addrs;
struct tgsi_exec_vector *Predicates;
@@ -229,6 +266,8 @@ struct tgsi_exec_machine
/* GEOMETRY processor only. */
unsigned *Primitives;
+ unsigned NumOutputs;
+ unsigned MaxGeometryShaderOutputs;
/* FRAGMENT processor only. */
const struct tgsi_interp_coef *InterpCoefs;
@@ -242,6 +281,12 @@ struct tgsi_exec_machine
uint FuncMask; /**< For function calls */
uint ExecMask; /**< = CondMask & LoopMask */
+ /* Current switch-case state. */
+ struct tgsi_switch_record Switch;
+
+ /* Current break type. */
+ enum tgsi_break_type BreakType;
+
/** Condition mask stack (for nested conditionals) */
uint CondStack[TGSI_EXEC_MAX_COND_NESTING];
int CondStackTop;
@@ -262,6 +307,13 @@ struct tgsi_exec_machine
uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
int ContStackTop;
+ /** Switch case stack */
+ struct tgsi_switch_record SwitchStack[TGSI_EXEC_MAX_SWITCH_NESTING];
+ int SwitchStackTop;
+
+ enum tgsi_break_type BreakStack[TGSI_EXEC_MAX_BREAK_STACK];
+ int BreakStackTop;
+
/** Function execution mask stack (for executing subroutine code) */
uint FuncStack[TGSI_EXEC_MAX_CALL_NESTING];
int FuncStackTop;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index be375cabb8..de0e09cdba 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -119,7 +119,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 1, 1, 0, 0, 0, 0, "NOT", TGSI_OPCODE_NOT },
{ 1, 1, 0, 0, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC },
{ 1, 2, 0, 0, 0, 0, "SHL", TGSI_OPCODE_SHL },
- { 1, 2, 0, 0, 0, 0, "SHR", TGSI_OPCODE_SHR },
+ { 0, 0, 0, 0, 0, 0, "", 88 }, /* removed */
{ 1, 2, 0, 0, 0, 0, "AND", TGSI_OPCODE_AND },
{ 1, 2, 0, 0, 0, 0, "OR", TGSI_OPCODE_OR },
{ 1, 2, 0, 0, 0, 0, "MOD", TGSI_OPCODE_MOD },
@@ -149,7 +149,33 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 0, 1, 0, 0, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC },
{ 0, 1, 0, 0, 0, 0, "KIL", TGSI_OPCODE_KIL },
{ 0, 0, 0, 0, 0, 0, "END", TGSI_OPCODE_END },
- { 0, 0, 0, 0, 0, 0, "", 118 } /* removed */
+ { 0, 0, 0, 0, 0, 0, "", 118 }, /* removed */
+ { 1, 1, 0, 0, 0, 0, "F2I", TGSI_OPCODE_F2I },
+ { 1, 2, 0, 0, 0, 0, "IDIV", TGSI_OPCODE_IDIV },
+ { 1, 2, 0, 0, 0, 0, "IMAX", TGSI_OPCODE_IMAX },
+ { 1, 2, 0, 0, 0, 0, "IMIN", TGSI_OPCODE_IMIN },
+ { 1, 1, 0, 0, 0, 0, "INEG", TGSI_OPCODE_INEG },
+ { 1, 2, 0, 0, 0, 0, "ISGE", TGSI_OPCODE_ISGE },
+ { 1, 2, 0, 0, 0, 0, "ISHR", TGSI_OPCODE_ISHR },
+ { 1, 2, 0, 0, 0, 0, "ISLT", TGSI_OPCODE_ISLT },
+ { 1, 1, 0, 0, 0, 0, "F2U", TGSI_OPCODE_F2U },
+ { 1, 1, 0, 0, 0, 0, "U2F", TGSI_OPCODE_U2F },
+ { 1, 2, 0, 0, 0, 0, "UADD", TGSI_OPCODE_UADD },
+ { 1, 2, 0, 0, 0, 0, "UDIV", TGSI_OPCODE_UDIV },
+ { 1, 3, 0, 0, 0, 0, "UMAD", TGSI_OPCODE_UMAD },
+ { 1, 2, 0, 0, 0, 0, "UMAX", TGSI_OPCODE_UMAX },
+ { 1, 2, 0, 0, 0, 0, "UMIN", TGSI_OPCODE_UMIN },
+ { 1, 2, 0, 0, 0, 0, "UMOD", TGSI_OPCODE_UMOD },
+ { 1, 2, 0, 0, 0, 0, "UMUL", TGSI_OPCODE_UMUL },
+ { 1, 2, 0, 0, 0, 0, "USEQ", TGSI_OPCODE_USEQ },
+ { 1, 2, 0, 0, 0, 0, "USGE", TGSI_OPCODE_USGE },
+ { 1, 2, 0, 0, 0, 0, "USHR", TGSI_OPCODE_USHR },
+ { 1, 2, 0, 0, 0, 0, "USLT", TGSI_OPCODE_USLT },
+ { 1, 2, 0, 0, 0, 0, "USNE", TGSI_OPCODE_USNE },
+ { 0, 1, 0, 0, 0, 0, "SWITCH", TGSI_OPCODE_SWITCH },
+ { 0, 1, 0, 0, 0, 0, "CASE", TGSI_OPCODE_CASE },
+ { 0, 0, 0, 0, 0, 0, "DEFAULT", TGSI_OPCODE_DEFAULT },
+ { 0, 0, 0, 0, 0, 0, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH }
};
const struct tgsi_opcode_info *
diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
index b34263da48..e4af15c156 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
@@ -124,7 +124,6 @@ OP11(I2F)
OP11(NOT)
OP11(TRUNC)
OP12(SHL)
-OP12(SHR)
OP12(AND)
OP12(OR)
OP12(MOD)
@@ -146,6 +145,28 @@ OP01(IFC)
OP01(BREAKC)
OP01(KIL)
OP00(END)
+OP11(F2I)
+OP12(IDIV)
+OP12(IMAX)
+OP12(IMIN)
+OP11(INEG)
+OP12(ISGE)
+OP12(ISHR)
+OP12(ISLT)
+OP11(F2U)
+OP11(U2F)
+OP12(UADD)
+OP12(UDIV)
+OP13(UMAD)
+OP12(UMAX)
+OP12(UMIN)
+OP12(UMOD)
+OP12(UMUL)
+OP12(USEQ)
+OP12(USGE)
+OP12(USHR)
+OP12(USLT)
+OP12(USNE)
#undef OP00
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index fa65ecb997..8c7062d850 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -119,17 +119,29 @@ tgsi_parse_token(
case TGSI_TOKEN_TYPE_IMMEDIATE:
{
struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate;
+ uint imm_count;
memset(imm, 0, sizeof *imm);
copy_token(&imm->Immediate, &token);
+ imm_count = imm->Immediate.NrTokens - 1;
+
switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
- {
- uint imm_count = imm->Immediate.NrTokens - 1;
- for (i = 0; i < imm_count; i++) {
- next_token(ctx, &imm->u[i]);
- }
+ for (i = 0; i < imm_count; i++) {
+ next_token(ctx, &imm->u[i].Float);
+ }
+ break;
+
+ case TGSI_IMM_UINT32:
+ for (i = 0; i < imm_count; i++) {
+ next_token(ctx, &imm->u[i].Uint);
+ }
+ break;
+
+ case TGSI_IMM_INT32:
+ for (i = 0; i < imm_count; i++) {
+ next_token(ctx, &imm->u[i].Int);
}
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
index 138d2d095b..ad553c71a5 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
@@ -51,7 +51,8 @@
* Since it's pretty much impossible to form PPC vector immediates, load
* them from memory here:
*/
-const float ppc_builtin_constants[] ALIGN16_ATTRIB = {
+PIPE_ALIGN_VAR(16) const float
+ppc_builtin_constants[] = {
1.0f, -128.0f, 128.0, 0.0
};
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index c27579e794..e1e4f97967 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -26,32 +26,112 @@
**************************************************************************/
#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_prim.h"
+#include "cso_cache/cso_hash.h"
#include "tgsi_sanity.h"
#include "tgsi_info.h"
#include "tgsi_iterate.h"
-typedef uint reg_flag;
-
-#define BITS_IN_REG_FLAG (sizeof( reg_flag ) * 8)
-
-#define MAX_REGISTERS 1024
-#define MAX_REG_FLAGS ((MAX_REGISTERS + BITS_IN_REG_FLAG - 1) / BITS_IN_REG_FLAG)
+typedef struct {
+ uint file : 28;
+ /* max 2 dimensions */
+ uint dimensions : 4;
+ uint indices[2];
+} scan_register;
struct sanity_check_ctx
{
struct tgsi_iterate_context iter;
+ struct cso_hash *regs_decl;
+ struct cso_hash *regs_used;
+ struct cso_hash *regs_ind_used;
- reg_flag regs_decl[TGSI_FILE_COUNT][MAX_REG_FLAGS];
- reg_flag regs_used[TGSI_FILE_COUNT][MAX_REG_FLAGS];
- boolean regs_ind_used[TGSI_FILE_COUNT];
uint num_imms;
uint num_instructions;
uint index_of_END;
uint errors;
uint warnings;
+ uint implied_array_size;
};
+static INLINE unsigned
+scan_register_key(const scan_register *reg)
+{
+ unsigned key = reg->file;
+ key |= (reg->indices[0] << 4);
+ key |= (reg->indices[1] << 18);
+
+ return key;
+}
+
+static void
+fill_scan_register1d(scan_register *reg,
+ uint file, uint index)
+{
+ reg->file = file;
+ reg->dimensions = 1;
+ reg->indices[0] = index;
+ reg->indices[1] = 0;
+}
+
+static void
+fill_scan_register2d(scan_register *reg,
+ uint file, uint index1, uint index2)
+{
+ reg->file = file;
+ reg->dimensions = 2;
+ reg->indices[0] = index1;
+ reg->indices[1] = index2;
+}
+
+static void
+scan_register_dst(scan_register *reg,
+ struct tgsi_full_dst_register *dst)
+{
+ fill_scan_register1d(reg,
+ dst->Register.File,
+ dst->Register.Index);
+}
+
+static void
+scan_register_src(scan_register *reg,
+ struct tgsi_full_src_register *src)
+{
+ if (src->Register.Dimension) {
+ /*FIXME: right now we don't support indirect
+ * multidimensional addressing */
+ debug_assert(!src->Dimension.Indirect);
+ fill_scan_register2d(reg,
+ src->Register.File,
+ src->Register.Index,
+ src->Dimension.Index);
+ } else {
+ fill_scan_register1d(reg,
+ src->Register.File,
+ src->Register.Index);
+ }
+}
+
+static scan_register *
+create_scan_register_src(struct tgsi_full_src_register *src)
+{
+ scan_register *reg = MALLOC(sizeof(scan_register));
+ scan_register_src(reg, src);
+
+ return reg;
+}
+
+static scan_register *
+create_scan_register_dst(struct tgsi_full_dst_register *dst)
+{
+ scan_register *reg = MALLOC(sizeof(scan_register));
+ scan_register_dst(reg, dst);
+
+ return reg;
+}
+
static void
report_error(
struct sanity_check_ctx *ctx,
@@ -99,12 +179,12 @@ check_file_name(
static boolean
is_register_declared(
struct sanity_check_ctx *ctx,
- uint file,
- int index )
+ const scan_register *reg)
{
- assert( index >= 0 && index < MAX_REGISTERS );
-
- return (ctx->regs_decl[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
+ void *data = cso_hash_find_data_from_template(
+ ctx->regs_decl, scan_register_key(reg),
+ (void*)reg, sizeof(scan_register));
+ return data ? TRUE : FALSE;
}
static boolean
@@ -112,23 +192,37 @@ is_any_register_declared(
struct sanity_check_ctx *ctx,
uint file )
{
- uint i;
+ struct cso_hash_iter iter =
+ cso_hash_first_node(ctx->regs_decl);
- for (i = 0; i < MAX_REG_FLAGS; i++)
- if (ctx->regs_decl[file][i])
+ while (!cso_hash_iter_is_null(iter)) {
+ scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
+ if (reg->file == file)
return TRUE;
+ iter = cso_hash_iter_next(iter);
+ }
+
return FALSE;
}
static boolean
is_register_used(
struct sanity_check_ctx *ctx,
- uint file,
- int index )
+ scan_register *reg)
{
- assert( index < MAX_REGISTERS );
+ void *data = cso_hash_find_data_from_template(
+ ctx->regs_used, scan_register_key(reg),
+ reg, sizeof(scan_register));
+ return data ? TRUE : FALSE;
+}
+
- return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
+static boolean
+is_ind_register_used(
+ struct sanity_check_ctx *ctx,
+ scan_register *reg)
+{
+ return cso_hash_contains(ctx->regs_ind_used, reg->file);
}
static const char *file_names[TGSI_FILE_COUNT] =
@@ -148,31 +242,42 @@ static const char *file_names[TGSI_FILE_COUNT] =
static boolean
check_register_usage(
struct sanity_check_ctx *ctx,
- uint file,
- int index,
+ scan_register *reg,
const char *name,
boolean indirect_access )
{
- if (!check_file_name( ctx, file ))
+ if (!check_file_name( ctx, reg->file )) {
+ FREE(reg);
return FALSE;
+ }
if (indirect_access) {
/* Note that 'index' is an offset relative to the value of the
- * address register. No range checking done here.
- */
- if (!is_any_register_declared( ctx, file ))
- report_error( ctx, "%s: Undeclared %s register", file_names[file], name );
- ctx->regs_ind_used[file] = TRUE;
+ * address register. No range checking done here.*/
+ reg->indices[0] = 0;
+ reg->indices[1] = 0;
+ if (!is_any_register_declared( ctx, reg->file ))
+ report_error( ctx, "%s: Undeclared %s register", file_names[reg->file], name );
+ if (!is_ind_register_used(ctx, reg))
+ cso_hash_insert(ctx->regs_ind_used, reg->file, reg);
+ else
+ FREE(reg);
}
else {
- if (index < 0 || index >= MAX_REGISTERS) {
- report_error( ctx, "%s[%d]: Invalid %s index", file_names[file], index, name );
- return FALSE;
+ if (!is_register_declared( ctx, reg )) {
+ if (reg->dimensions == 2) {
+ report_error( ctx, "%s[%d][%d]: Undeclared %s register", file_names[reg->file],
+ reg->indices[0], reg->indices[1], name );
+ }
+ else {
+ report_error( ctx, "%s[%d]: Undeclared %s register", file_names[reg->file],
+ reg->indices[0], name );
+ }
}
-
- if (!is_register_declared( ctx, file, index ))
- report_error( ctx, "%s[%d]: Undeclared %s register", file_names[file], index, name );
- ctx->regs_used[file][index / BITS_IN_REG_FLAG] |= (1 << (index % BITS_IN_REG_FLAG));
+ if (!is_register_used( ctx, reg ))
+ cso_hash_insert(ctx->regs_used, scan_register_key(reg), reg);
+ else
+ FREE(reg);
}
return TRUE;
}
@@ -210,35 +315,35 @@ iter_instruction(
* Mark the registers as used.
*/
for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
+ scan_register *reg = create_scan_register_dst(&inst->Dst[i]);
check_register_usage(
ctx,
- inst->Dst[i].Register.File,
- inst->Dst[i].Register.Index,
+ reg,
"destination",
FALSE );
}
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
+ scan_register *reg = create_scan_register_src(&inst->Src[i]);
check_register_usage(
ctx,
- inst->Src[i].Register.File,
- inst->Src[i].Register.Index,
+ reg,
"source",
(boolean)inst->Src[i].Register.Indirect );
if (inst->Src[i].Register.Indirect) {
- uint file;
- int index;
+ scan_register *ind_reg = MALLOC(sizeof(scan_register));
- file = inst->Src[i].Indirect.File;
- index = inst->Src[i].Indirect.Index;
+ fill_scan_register1d(ind_reg,
+ inst->Src[i].Indirect.File,
+ inst->Src[i].Indirect.Index);
+ if (!(ind_reg->file == TGSI_FILE_ADDRESS || ind_reg->file == TGSI_FILE_LOOP) ||
+ ind_reg->indices[0] != 0) {
+ report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]");
+ }
check_register_usage(
ctx,
- file,
- index,
+ ind_reg,
"indirect",
FALSE );
- if (!(file == TGSI_FILE_ADDRESS || file == TGSI_FILE_LOOP) || index != 0) {
- report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]");
- }
}
}
@@ -266,6 +371,19 @@ iter_instruction(
return TRUE;
}
+static void
+check_and_declare(struct sanity_check_ctx *ctx,
+ scan_register *reg)
+{
+ if (is_register_declared( ctx, reg))
+ report_error( ctx, "%s[%u]: The same register declared more than once",
+ file_names[reg->file], reg->indices[0] );
+ cso_hash_insert(ctx->regs_decl,
+ scan_register_key(reg),
+ reg);
+}
+
+
static boolean
iter_declaration(
struct tgsi_iterate_context *iter,
@@ -287,9 +405,21 @@ iter_declaration(
if (!check_file_name( ctx, file ))
return TRUE;
for (i = decl->Range.First; i <= decl->Range.Last; i++) {
- if (is_register_declared( ctx, file, i ))
- report_error( ctx, "%s[%u]: The same register declared more than once", file_names[file], i );
- ctx->regs_decl[file][i / BITS_IN_REG_FLAG] |= (1 << (i % BITS_IN_REG_FLAG));
+ /* declared TGSI_FILE_INPUT's for geometry processor
+ * have an implied second dimension */
+ if (file == TGSI_FILE_INPUT &&
+ ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
+ uint vert;
+ for (vert = 0; vert < ctx->implied_array_size; ++vert) {
+ scan_register *reg = MALLOC(sizeof(scan_register));
+ fill_scan_register2d(reg, file, vert, i);
+ check_and_declare(ctx, reg);
+ }
+ } else {
+ scan_register *reg = MALLOC(sizeof(scan_register));
+ fill_scan_register1d(reg, file, i);
+ check_and_declare(ctx, reg);
+ }
}
return TRUE;
@@ -301,8 +431,7 @@ iter_immediate(
struct tgsi_full_immediate *imm )
{
struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
-
- assert( ctx->num_imms < MAX_REGISTERS );
+ scan_register *reg;
/* No immediates allowed after the first instruction.
*/
@@ -311,12 +440,16 @@ iter_immediate(
/* Mark the register as declared.
*/
- ctx->regs_decl[TGSI_FILE_IMMEDIATE][ctx->num_imms / BITS_IN_REG_FLAG] |= (1 << (ctx->num_imms % BITS_IN_REG_FLAG));
+ reg = MALLOC(sizeof(scan_register));
+ fill_scan_register1d(reg, TGSI_FILE_IMMEDIATE, ctx->num_imms);
+ cso_hash_insert(ctx->regs_decl, scan_register_key(reg), reg);
ctx->num_imms++;
/* Check data type validity.
*/
- if (imm->Immediate.DataType != TGSI_IMM_FLOAT32) {
+ if (imm->Immediate.DataType != TGSI_IMM_FLOAT32 &&
+ imm->Immediate.DataType != TGSI_IMM_UINT32 &&
+ imm->Immediate.DataType != TGSI_IMM_INT32) {
report_error( ctx, "(%u): Invalid immediate data type", imm->Immediate.DataType );
return TRUE;
}
@@ -330,8 +463,12 @@ iter_property(
struct tgsi_iterate_context *iter,
struct tgsi_full_property *prop )
{
- /*struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;*/
+ struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
+ if (iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY &&
+ prop->Property.PropertyName == TGSI_PROPERTY_GS_INPUT_PRIM) {
+ ctx->implied_array_size = u_vertices_per_prim(prop->u[0].Data);
+ }
return TRUE;
}
@@ -340,7 +477,6 @@ epilog(
struct tgsi_iterate_context *iter )
{
struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;
- uint file;
/* There must be an END instruction somewhere.
*/
@@ -350,13 +486,17 @@ epilog(
/* Check if all declared registers were used.
*/
- for (file = TGSI_FILE_NULL; file < TGSI_FILE_COUNT; file++) {
- uint i;
-
- for (i = 0; i < MAX_REGISTERS; i++) {
- if (is_register_declared( ctx, file, i ) && !is_register_used( ctx, file, i ) && !ctx->regs_ind_used[file]) {
- report_warning( ctx, "%s[%u]: Register never used", file_names[file], i );
+ {
+ struct cso_hash_iter iter =
+ cso_hash_first_node(ctx->regs_decl);
+
+ while (!cso_hash_iter_is_null(iter)) {
+ scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
+ if (!is_register_used(ctx, reg) && !is_ind_register_used(ctx, reg)) {
+ report_warning( ctx, "%s[%u]: Register never used",
+ file_names[reg->file], reg->indices[0] );
}
+ iter = cso_hash_iter_next(iter);
}
}
@@ -368,6 +508,19 @@ epilog(
return TRUE;
}
+static void
+regs_hash_destroy(struct cso_hash *hash)
+{
+ struct cso_hash_iter iter = cso_hash_first_node(hash);
+ while (!cso_hash_iter_is_null(iter)) {
+ scan_register *reg = (scan_register *)cso_hash_iter_data(iter);
+ iter = cso_hash_erase(hash, iter);
+ assert(reg->file < TGSI_FILE_COUNT);
+ FREE(reg);
+ }
+ cso_hash_delete(hash);
+}
+
boolean
tgsi_sanity_check(
const struct tgsi_token *tokens )
@@ -381,18 +534,23 @@ tgsi_sanity_check(
ctx.iter.iterate_property = iter_property;
ctx.iter.epilog = epilog;
- memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) );
- memset( ctx.regs_used, 0, sizeof( ctx.regs_used ) );
- memset( ctx.regs_ind_used, 0, sizeof( ctx.regs_ind_used ) );
+ ctx.regs_decl = cso_hash_create();
+ ctx.regs_used = cso_hash_create();
+ ctx.regs_ind_used = cso_hash_create();
+
ctx.num_imms = 0;
ctx.num_instructions = 0;
ctx.index_of_END = ~0;
ctx.errors = 0;
ctx.warnings = 0;
+ ctx.implied_array_size = 0;
if (!tgsi_iterate_shader( tokens, &ctx.iter ))
return FALSE;
+ regs_hash_destroy(ctx.regs_decl);
+ regs_hash_destroy(ctx.regs_used);
+ regs_hash_destroy(ctx.regs_ind_used);
return ctx.errors == 0;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index 0f48b0dc3a..a6cc773003 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -229,8 +229,8 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
/* Do a whole bunch of checks for a simple move */
if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV ||
- src->Register.File != TGSI_FILE_INPUT ||
- src->Register.File != TGSI_FILE_SYSTEM_VALUE ||
+ (src->Register.File != TGSI_FILE_INPUT &&
+ src->Register.File != TGSI_FILE_SYSTEM_VALUE) ||
dst->Register.File != TGSI_FILE_OUTPUT ||
src->Register.Index != dst->Register.Index ||
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index d63c75dafb..a85cc4659e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -2,6 +2,7 @@
*
* Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * Copyright 2009-2010 VMware, Inc. All rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
@@ -1418,13 +1419,13 @@ fetch_texel( struct tgsi_sampler **sampler,
sampler, *sampler,
store );
- debug_printf("lodbias %f\n", store[12]);
-
for (j = 0; j < 4; j++)
- debug_printf("sample %d texcoord %f %f\n",
+ debug_printf("sample %d texcoord %f %f %f lodbias %f\n",
j,
store[0+j],
- store[4+j]);
+ store[4+j],
+ store[8 + j],
+ store[12 + j]);
#endif
{
@@ -1433,7 +1434,8 @@ fetch_texel( struct tgsi_sampler **sampler,
&store[0], /* s */
&store[4], /* t */
&store[8], /* r */
- store[12], /* lodbias */
+ &store[12], /* lodbias */
+ tgsi_sampler_lod_bias,
rgba); /* results */
memcpy( store, rgba, 16 * sizeof(float));
@@ -2144,40 +2146,50 @@ emit_instruction(
break;
case TGSI_OPCODE_XPD:
+ /* Note: we do all stores after all operands have been fetched
+ * to avoid src/dst register aliasing issues for an instruction
+ * such as: XPD TEMP[2].xyz, TEMP[0], TEMP[2];
+ */
if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) {
- FETCH( func, *inst, 1, 1, CHAN_Z );
- FETCH( func, *inst, 3, 0, CHAN_Z );
+ FETCH( func, *inst, 1, 1, CHAN_Z ); /* xmm[1] = src[1].z */
+ FETCH( func, *inst, 3, 0, CHAN_Z ); /* xmm[3] = src[0].z */
}
if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
- FETCH( func, *inst, 0, 0, CHAN_Y );
- FETCH( func, *inst, 4, 1, CHAN_Y );
+ FETCH( func, *inst, 0, 0, CHAN_Y ); /* xmm[0] = src[0].y */
+ FETCH( func, *inst, 4, 1, CHAN_Y ); /* xmm[4] = src[1].y */
}
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) {
- emit_MOV( func, 2, 0 );
- emit_mul( func, 2, 1 );
- emit_MOV( func, 5, 3 );
- emit_mul( func, 5, 4 );
- emit_sub( func, 2, 5 );
- STORE( func, *inst, 2, 0, CHAN_X );
+ emit_MOV( func, 7, 0 ); /* xmm[7] = xmm[0] */
+ emit_mul( func, 7, 1 ); /* xmm[7] = xmm[2] * xmm[1] */
+ emit_MOV( func, 5, 3 ); /* xmm[5] = xmm[3] */
+ emit_mul( func, 5, 4 ); /* xmm[5] = xmm[5] * xmm[4] */
+ emit_sub( func, 7, 5 ); /* xmm[7] = xmm[2] - xmm[5] */
+ /* store xmm[7] in dst.x below */
}
if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ||
IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) {
- FETCH( func, *inst, 2, 1, CHAN_X );
- FETCH( func, *inst, 5, 0, CHAN_X );
+ FETCH( func, *inst, 2, 1, CHAN_X ); /* xmm[2] = src[1].x */
+ FETCH( func, *inst, 5, 0, CHAN_X ); /* xmm[5] = src[0].x */
}
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) {
- emit_mul( func, 3, 2 );
- emit_mul( func, 1, 5 );
- emit_sub( func, 3, 1 );
- STORE( func, *inst, 3, 0, CHAN_Y );
+ emit_mul( func, 3, 2 ); /* xmm[3] = xmm[3] * xmm[2] */
+ emit_mul( func, 1, 5 ); /* xmm[1] = xmm[1] * xmm[5] */
+ emit_sub( func, 3, 1 ); /* xmm[3] = xmm[3] - xmm[1] */
+ /* store xmm[3] in dst.y below */
}
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) {
- emit_mul( func, 5, 4 );
- emit_mul( func, 0, 2 );
- emit_sub( func, 5, 0 );
- STORE( func, *inst, 5, 0, CHAN_Z );
+ emit_mul( func, 5, 4 ); /* xmm[5] = xmm[5] * xmm[4] */
+ emit_mul( func, 0, 2 ); /* xmm[0] = xmm[0] * xmm[2] */
+ emit_sub( func, 5, 0 ); /* xmm[5] = xmm[5] - xmm[0] */
+ STORE( func, *inst, 5, 0, CHAN_Z ); /* dst.z = xmm[5] */
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) {
+ STORE( func, *inst, 7, 0, CHAN_X ); /* dst.x = xmm[7] */
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) {
+ STORE( func, *inst, 3, 0, CHAN_Y ); /* dst.y = xmm[3] */
}
IF_IS_DST0_CHANNEL_ENABLED( *inst, CHAN_W ) {
emit_tempf(
@@ -2506,7 +2518,7 @@ emit_instruction(
break;
case TGSI_OPCODE_TXL:
- emit_tex( func, inst, TRUE, FALSE );
+ return 0;
break;
case TGSI_OPCODE_TXP:
@@ -2578,7 +2590,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_SHR:
+ case TGSI_OPCODE_ISHR:
return 0;
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index f000958bfc..9fcffeda36 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -27,7 +27,9 @@
#include "util/u_debug.h"
#include "util/u_memory.h"
+#include "util/u_prim.h"
#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
#include "tgsi_text.h"
#include "tgsi_build.h"
#include "tgsi_info.h"
@@ -61,18 +63,20 @@ static boolean uprcase( char c )
}
/*
- * Ignore case of str1 and assume str2 is already uppercase.
+ * Ignore case of str1 and assume str1 is already uppercase.
* Return TRUE iff str1 and str2 are equal.
*/
static int
streq_nocase_uprcase(const char *str1,
const char *str2)
{
- while (*str1 && uprcase(*str1) == *str2) {
+ while (*str1 && *str2) {
+ if (*str1 != uprcase(*str2))
+ return FALSE;
str1++;
str2++;
}
- return *str1 == *str2;
+ return TRUE;
}
static boolean str_match_no_case( const char **pcur, const char *str )
@@ -193,11 +197,26 @@ struct translate_ctx
struct tgsi_token *tokens_cur;
struct tgsi_token *tokens_end;
struct tgsi_header *header;
+ unsigned processor : 4;
+ int implied_array_size : 5;
};
static void report_error( struct translate_ctx *ctx, const char *msg )
{
- debug_printf( "\nError: %s", msg );
+ int line = 1;
+ int column = 1;
+ const char *itr = ctx->text;
+
+ while (itr != ctx->cur) {
+ if (*itr == '\n') {
+ column = 1;
+ ++line;
+ }
+ ++column;
+ ++itr;
+ }
+
+ debug_printf( "\nTGSI asm error: %s [%d : %d] \n", msg, line, column );
}
/* Parse shader header.
@@ -229,6 +248,7 @@ static boolean parse_header( struct translate_ctx *ctx )
if (ctx->tokens_cur >= ctx->tokens_end)
return FALSE;
*(struct tgsi_processor *) ctx->tokens_cur++ = tgsi_build_processor( processor, ctx->header );
+ ctx->processor = processor;
return TRUE;
}
@@ -325,92 +345,36 @@ parse_opt_writemask(
return TRUE;
}
-/* <register_file_bracket> ::= <file> `['
- */
static boolean
-parse_register_file_bracket(
- struct translate_ctx *ctx,
- uint *file )
-{
- if (!parse_file( &ctx->cur, file )) {
- report_error( ctx, "Unknown register file" );
- return FALSE;
- }
- eat_opt_white( &ctx->cur );
- if (*ctx->cur != '[') {
- report_error( ctx, "Expected `['" );
- return FALSE;
- }
- ctx->cur++;
- return TRUE;
-}
+parse_register_dst( struct translate_ctx *ctx,
+ uint *file,
+ int *index );
-/* <register_file_bracket_index> ::= <register_file_bracket> <uint>
- */
-static boolean
-parse_register_file_bracket_index(
- struct translate_ctx *ctx,
- uint *file,
- int *index )
-{
- uint uindex;
+struct parsed_src_bracket {
+ int index;
- if (!parse_register_file_bracket( ctx, file ))
- return FALSE;
- eat_opt_white( &ctx->cur );
- if (!parse_uint( &ctx->cur, &uindex )) {
- report_error( ctx, "Expected literal unsigned integer" );
- return FALSE;
- }
- *index = (int) uindex;
- return TRUE;
-}
+ uint ind_file;
+ int ind_index;
+ uint ind_comp;
+};
-/* Parse destination register operand.
- * <register_dst> ::= <register_file_bracket_index> `]'
- */
-static boolean
-parse_register_dst(
- struct translate_ctx *ctx,
- uint *file,
- int *index )
-{
- if (!parse_register_file_bracket_index( ctx, file, index ))
- return FALSE;
- eat_opt_white( &ctx->cur );
- if (*ctx->cur != ']') {
- report_error( ctx, "Expected `]'" );
- return FALSE;
- }
- ctx->cur++;
- return TRUE;
-}
-/* Parse source register operand.
- * <register_src> ::= <register_file_bracket_index> `]' |
- * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' |
- * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' |
- * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]'
- */
static boolean
-parse_register_src(
+parse_register_src_bracket(
struct translate_ctx *ctx,
- uint *file,
- int *index,
- uint *ind_file,
- int *ind_index,
- uint *ind_comp)
+ struct parsed_src_bracket *brackets)
{
const char *cur;
uint uindex;
- *ind_comp = TGSI_SWIZZLE_X;
- if (!parse_register_file_bracket( ctx, file ))
- return FALSE;
+ memset(brackets, 0, sizeof(struct parsed_src_bracket));
+
eat_opt_white( &ctx->cur );
+
cur = ctx->cur;
- if (parse_file( &cur, ind_file )) {
- if (!parse_register_dst( ctx, ind_file, ind_index ))
+ if (parse_file( &cur, &brackets->ind_file )) {
+ if (!parse_register_dst( ctx, &brackets->ind_file,
+ &brackets->ind_index ))
return FALSE;
eat_opt_white( &ctx->cur );
@@ -420,16 +384,16 @@ parse_register_src(
switch (uprcase(*ctx->cur)) {
case 'X':
- *ind_comp = TGSI_SWIZZLE_X;
+ brackets->ind_comp = TGSI_SWIZZLE_X;
break;
case 'Y':
- *ind_comp = TGSI_SWIZZLE_Y;
+ brackets->ind_comp = TGSI_SWIZZLE_Y;
break;
case 'Z':
- *ind_comp = TGSI_SWIZZLE_Z;
+ brackets->ind_comp = TGSI_SWIZZLE_Z;
break;
case 'W':
- *ind_comp = TGSI_SWIZZLE_W;
+ brackets->ind_comp = TGSI_SWIZZLE_W;
break;
default:
report_error(ctx, "Expected indirect register swizzle component `x', `y', `z' or `w'");
@@ -450,12 +414,12 @@ parse_register_src(
return FALSE;
}
if (negate)
- *index = -(int) uindex;
+ brackets->index = -(int) uindex;
else
- *index = (int) uindex;
+ brackets->index = (int) uindex;
}
else {
- *index = 0;
+ brackets->index = 0;
}
}
else {
@@ -463,9 +427,9 @@ parse_register_src(
report_error( ctx, "Expected literal unsigned integer" );
return FALSE;
}
- *index = (int) uindex;
- *ind_file = TGSI_FILE_NULL;
- *ind_index = 0;
+ brackets->index = (int) uindex;
+ brackets->ind_file = TGSI_FILE_NULL;
+ brackets->ind_index = 0;
}
eat_opt_white( &ctx->cur );
if (*ctx->cur != ']') {
@@ -476,20 +440,123 @@ parse_register_src(
return TRUE;
}
-/* Parse register declaration.
- * <register_dcl> ::= <register_file_bracket_index> `]' |
- * <register_file_bracket_index> `..' <index> `]'
+static boolean
+parse_opt_register_src_bracket(
+ struct translate_ctx *ctx,
+ struct parsed_src_bracket *brackets,
+ int *parsed_brackets)
+{
+ const char *cur = ctx->cur;
+
+ *parsed_brackets = 0;
+
+ eat_opt_white( &cur );
+ if (cur[0] == '[') {
+ ++cur;
+ ctx->cur = cur;
+
+ if (!parse_register_src_bracket(ctx, brackets))
+ return FALSE;
+
+ *parsed_brackets = 1;
+ }
+
+ return TRUE;
+}
+
+/* <register_file_bracket> ::= <file> `['
*/
static boolean
-parse_register_dcl(
+parse_register_file_bracket(
+ struct translate_ctx *ctx,
+ uint *file )
+{
+ if (!parse_file( &ctx->cur, file )) {
+ report_error( ctx, "Unknown register file" );
+ return FALSE;
+ }
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != '[') {
+ report_error( ctx, "Expected `['" );
+ return FALSE;
+ }
+ ctx->cur++;
+ return TRUE;
+}
+
+/* <register_file_bracket_index> ::= <register_file_bracket> <uint>
+ */
+static boolean
+parse_register_file_bracket_index(
+ struct translate_ctx *ctx,
+ uint *file,
+ int *index )
+{
+ uint uindex;
+
+ if (!parse_register_file_bracket( ctx, file ))
+ return FALSE;
+ eat_opt_white( &ctx->cur );
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ report_error( ctx, "Expected literal unsigned integer" );
+ return FALSE;
+ }
+ *index = (int) uindex;
+ return TRUE;
+}
+
+/* Parse source register operand.
+ * <register_src> ::= <register_file_bracket_index> `]' |
+ * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `]' |
+ * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' |
+ * <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]'
+ */
+static boolean
+parse_register_src(
struct translate_ctx *ctx,
uint *file,
- int *first,
- int *last )
+ struct parsed_src_bracket *brackets)
+{
+
+ brackets->ind_comp = TGSI_SWIZZLE_X;
+ if (!parse_register_file_bracket( ctx, file ))
+ return FALSE;
+ if (!parse_register_src_bracket( ctx, brackets ))
+ return FALSE;
+
+ return TRUE;
+}
+
+struct parsed_dcl_bracket {
+ uint first;
+ uint last;
+};
+
+static boolean
+parse_register_dcl_bracket(
+ struct translate_ctx *ctx,
+ struct parsed_dcl_bracket *bracket)
{
- if (!parse_register_file_bracket_index( ctx, file, first ))
+ uint uindex;
+ memset(bracket, 0, sizeof(struct parsed_dcl_bracket));
+
+ eat_opt_white( &ctx->cur );
+
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ /* it can be an empty bracket [] which means its range
+ * is from 0 to some implied size */
+ if (ctx->cur[0] == ']' && ctx->implied_array_size != 0) {
+ bracket->first = 0;
+ bracket->last = ctx->implied_array_size - 1;
+ goto cleanup;
+ }
+ report_error( ctx, "Expected literal unsigned integer" );
return FALSE;
+ }
+ bracket->first = (int) uindex;
+
eat_opt_white( &ctx->cur );
+
if (ctx->cur[0] == '.' && ctx->cur[1] == '.') {
uint uindex;
@@ -499,12 +566,14 @@ parse_register_dcl(
report_error( ctx, "Expected literal integer" );
return FALSE;
}
- *last = (int) uindex;
+ bracket->last = (int) uindex;
eat_opt_white( &ctx->cur );
}
else {
- *last = *first;
+ bracket->last = bracket->first;
}
+
+cleanup:
if (*ctx->cur != ']') {
report_error( ctx, "Expected `]' or `..'" );
return FALSE;
@@ -513,6 +582,70 @@ parse_register_dcl(
return TRUE;
}
+/* Parse register declaration.
+ * <register_dcl> ::= <register_file_bracket_index> `]' |
+ * <register_file_bracket_index> `..' <index> `]'
+ */
+static boolean
+parse_register_dcl(
+ struct translate_ctx *ctx,
+ uint *file,
+ struct parsed_dcl_bracket *brackets,
+ int *num_brackets)
+{
+ const char *cur;
+
+ *num_brackets = 0;
+
+ if (!parse_register_file_bracket( ctx, file ))
+ return FALSE;
+ if (!parse_register_dcl_bracket( ctx, &brackets[0] ))
+ return FALSE;
+
+ *num_brackets = 1;
+
+ cur = ctx->cur;
+ eat_opt_white( &cur );
+
+ if (cur[0] == '[') {
+ ++cur;
+ ctx->cur = cur;
+ if (!parse_register_dcl_bracket( ctx, &brackets[1] ))
+ return FALSE;
+ /* for geometry shader we don't really care about
+ * the first brackets it's always the size of the
+ * input primitive. so we want to declare just
+ * the index relevant to the semantics which is in
+ * the second bracket */
+ if (ctx->processor == TGSI_PROCESSOR_GEOMETRY) {
+ brackets[0] = brackets[1];
+ }
+ *num_brackets = 2;
+ }
+
+ return TRUE;
+}
+
+
+/* Parse destination register operand.
+ * <register_dst> ::= <register_file_bracket_index> `]'
+ */
+static boolean
+parse_register_dst(
+ struct translate_ctx *ctx,
+ uint *file,
+ int *index )
+{
+ if (!parse_register_file_bracket_index( ctx, file, index ))
+ return FALSE;
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != ']') {
+ report_error( ctx, "Expected `]'" );
+ return FALSE;
+ }
+ ctx->cur++;
+ return TRUE;
+}
static boolean
parse_dst_operand(
@@ -582,37 +715,44 @@ parse_src_operand(
struct tgsi_full_src_register *src )
{
uint file;
- int index;
- uint ind_file;
- int ind_index;
- uint ind_comp;
uint swizzle[4];
boolean parsed_swizzle;
+ struct parsed_src_bracket bracket[2];
+ int parsed_opt_brackets;
if (*ctx->cur == '-') {
ctx->cur++;
eat_opt_white( &ctx->cur );
src->Register.Negate = 1;
}
-
+
if (*ctx->cur == '|') {
ctx->cur++;
eat_opt_white( &ctx->cur );
src->Register.Absolute = 1;
}
- if (!parse_register_src(ctx, &file, &index, &ind_file, &ind_index, &ind_comp))
+ if (!parse_register_src(ctx, &file, &bracket[0]))
+ return FALSE;
+ if (!parse_opt_register_src_bracket(ctx, &bracket[1], &parsed_opt_brackets))
return FALSE;
+
src->Register.File = file;
- src->Register.Index = index;
- if (ind_file != TGSI_FILE_NULL) {
+ src->Register.Index = bracket[0].index;
+ if (bracket[0].ind_file != TGSI_FILE_NULL) {
src->Register.Indirect = 1;
- src->Indirect.File = ind_file;
- src->Indirect.Index = ind_index;
- src->Indirect.SwizzleX = ind_comp;
- src->Indirect.SwizzleY = ind_comp;
- src->Indirect.SwizzleZ = ind_comp;
- src->Indirect.SwizzleW = ind_comp;
+ src->Indirect.File = bracket[0].ind_file;
+ src->Indirect.Index = bracket[0].ind_index;
+ src->Indirect.SwizzleX = bracket[0].ind_comp;
+ src->Indirect.SwizzleY = bracket[0].ind_comp;
+ src->Indirect.SwizzleZ = bracket[0].ind_comp;
+ src->Indirect.SwizzleW = bracket[0].ind_comp;
+ }
+ if (parsed_opt_brackets) {
+ src->Register.Dimension = 1;
+ src->Dimension.Indirect = 0;
+ src->Dimension.Dimension = 0;
+ src->Dimension.Index = bracket[1].index;
}
/* Parse optional swizzle.
@@ -791,7 +931,9 @@ static const char *semantic_names[TGSI_SEMANTIC_COUNT] =
"PSIZE",
"GENERIC",
"NORMAL",
- "FACE"
+ "FACE",
+ "EDGEFLAG",
+ "PRIM_ID"
};
static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] =
@@ -805,8 +947,8 @@ static boolean parse_declaration( struct translate_ctx *ctx )
{
struct tgsi_full_declaration decl;
uint file;
- int first;
- int last;
+ struct parsed_dcl_bracket brackets[2];
+ int num_brackets;
uint writemask;
const char *cur;
uint advance;
@@ -818,7 +960,7 @@ static boolean parse_declaration( struct translate_ctx *ctx )
report_error( ctx, "Syntax error" );
return FALSE;
}
- if (!parse_register_dcl( ctx, &file, &first, &last ))
+ if (!parse_register_dcl( ctx, &file, brackets, &num_brackets))
return FALSE;
if (!parse_opt_writemask( ctx, &writemask ))
return FALSE;
@@ -826,8 +968,8 @@ static boolean parse_declaration( struct translate_ctx *ctx )
decl = tgsi_default_full_declaration();
decl.Declaration.File = file;
decl.Declaration.UsageMask = writemask;
- decl.Range.First = first;
- decl.Range.Last = last;
+ decl.Range.First = brackets[0].first;
+ decl.Range.Last = brackets[0].last;
cur = ctx->cur;
eat_opt_white( &cur );
@@ -1027,7 +1169,7 @@ static boolean parse_property( struct translate_ctx *ctx )
}
for (property_name = 0; property_name < TGSI_PROPERTY_COUNT;
++property_name) {
- if (streq_nocase_uprcase(id, property_names[property_name])) {
+ if (streq_nocase_uprcase(property_names[property_name], id)) {
break;
}
}
@@ -1044,6 +1186,10 @@ static boolean parse_property( struct translate_ctx *ctx )
report_error( ctx, "Unknown primitive name as property!" );
return FALSE;
}
+ if (property_name == TGSI_PROPERTY_GS_INPUT_PRIM &&
+ ctx->processor == TGSI_PROCESSOR_GEOMETRY) {
+ ctx->implied_array_size = u_vertices_per_prim(values[0]);
+ }
break;
default:
if (!parse_uint(&ctx->cur, &values[0] )) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 1e730e5342..2b51672b8e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -64,6 +64,7 @@ struct ureg_tokens {
};
#define UREG_MAX_INPUT PIPE_MAX_ATTRIBS
+#define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS
#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS
#define UREG_MAX_CONSTANT_RANGE 32
#define UREG_MAX_IMMEDIATE 32
@@ -95,14 +96,26 @@ struct ureg_program
unsigned nr_gs_inputs;
struct {
+ unsigned index;
+ unsigned semantic_name;
+ unsigned semantic_index;
+ } system_value[UREG_MAX_SYSTEM_VALUE];
+ unsigned nr_system_values;
+
+ struct {
unsigned semantic_name;
unsigned semantic_index;
} output[UREG_MAX_OUTPUT];
unsigned nr_outputs;
struct {
- float v[4];
+ union {
+ float f[4];
+ unsigned u[4];
+ int i[4];
+ } value;
unsigned nr;
+ unsigned type;
} immediate[UREG_MAX_IMMEDIATE];
unsigned nr_immediates;
@@ -299,6 +312,25 @@ ureg_DECL_gs_input(struct ureg_program *ureg,
}
+struct ureg_src
+ureg_DECL_system_value(struct ureg_program *ureg,
+ unsigned index,
+ unsigned semantic_name,
+ unsigned semantic_index)
+{
+ if (ureg->nr_system_values < UREG_MAX_SYSTEM_VALUE) {
+ ureg->system_value[ureg->nr_system_values].index = index;
+ ureg->system_value[ureg->nr_system_values].semantic_name = semantic_name;
+ ureg->system_value[ureg->nr_system_values].semantic_index = semantic_index;
+ ureg->nr_system_values++;
+ } else {
+ set_bad(ureg);
+ }
+
+ return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, index);
+}
+
+
struct ureg_dst
ureg_DECL_output( struct ureg_program *ureg,
unsigned name,
@@ -486,22 +518,22 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
}
-
-
-static int match_or_expand_immediate( const float *v,
- unsigned nr,
- float *v2,
- unsigned *nr2,
- unsigned *swizzle )
+static int
+match_or_expand_immediate( const unsigned *v,
+ unsigned nr,
+ unsigned *v2,
+ unsigned *pnr2,
+ unsigned *swizzle )
{
+ unsigned nr2 = *pnr2;
unsigned i, j;
-
+
*swizzle = 0;
for (i = 0; i < nr; i++) {
boolean found = FALSE;
- for (j = 0; j < *nr2 && !found; j++) {
+ for (j = 0; j < nr2 && !found; j++) {
if (v[i] == v2[j]) {
*swizzle |= j << (i * 2);
found = TRUE;
@@ -509,24 +541,28 @@ static int match_or_expand_immediate( const float *v,
}
if (!found) {
- if (*nr2 >= 4)
+ if (nr2 >= 4) {
return FALSE;
+ }
- v2[*nr2] = v[i];
- *swizzle |= *nr2 << (i * 2);
- (*nr2)++;
+ v2[nr2] = v[i];
+ *swizzle |= nr2 << (i * 2);
+ nr2++;
}
}
+ /* Actually expand immediate only when fully succeeded.
+ */
+ *pnr2 = nr2;
return TRUE;
}
-
-
-struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
- const float *v,
- unsigned nr )
+static struct ureg_src
+decl_immediate( struct ureg_program *ureg,
+ const unsigned *v,
+ unsigned nr,
+ unsigned type )
{
unsigned i, j;
unsigned swizzle;
@@ -536,38 +572,82 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
*/
for (i = 0; i < ureg->nr_immediates; i++) {
- if (match_or_expand_immediate( v,
- nr,
- ureg->immediate[i].v,
- &ureg->immediate[i].nr,
- &swizzle ))
+ if (ureg->immediate[i].type != type) {
+ continue;
+ }
+ if (match_or_expand_immediate(v,
+ nr,
+ ureg->immediate[i].value.u,
+ &ureg->immediate[i].nr,
+ &swizzle)) {
goto out;
+ }
}
if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) {
i = ureg->nr_immediates++;
- if (match_or_expand_immediate( v,
- nr,
- ureg->immediate[i].v,
- &ureg->immediate[i].nr,
- &swizzle ))
+ ureg->immediate[i].type = type;
+ if (match_or_expand_immediate(v,
+ nr,
+ ureg->immediate[i].value.u,
+ &ureg->immediate[i].nr,
+ &swizzle)) {
goto out;
+ }
}
- set_bad( ureg );
+ set_bad(ureg);
out:
/* Make sure that all referenced elements are from this immediate.
* Has the effect of making size-one immediates into scalars.
*/
- for (j = nr; j < 4; j++)
+ for (j = nr; j < 4; j++) {
swizzle |= (swizzle & 0x3) << (j * 2);
+ }
- return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
- (swizzle >> 0) & 0x3,
- (swizzle >> 2) & 0x3,
- (swizzle >> 4) & 0x3,
- (swizzle >> 6) & 0x3);
+ return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i),
+ (swizzle >> 0) & 0x3,
+ (swizzle >> 2) & 0x3,
+ (swizzle >> 4) & 0x3,
+ (swizzle >> 6) & 0x3);
+}
+
+
+struct ureg_src
+ureg_DECL_immediate( struct ureg_program *ureg,
+ const float *v,
+ unsigned nr )
+{
+ union {
+ float f[4];
+ unsigned u[4];
+ } fu;
+ unsigned int i;
+
+ for (i = 0; i < nr; i++) {
+ fu.f[i] = v[i];
+ }
+
+ return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32);
+}
+
+
+struct ureg_src
+ureg_DECL_immediate_uint( struct ureg_program *ureg,
+ const unsigned *v,
+ unsigned nr )
+{
+ return decl_immediate(ureg, v, nr, TGSI_IMM_UINT32);
+}
+
+
+struct ureg_src
+ureg_DECL_immediate_int( struct ureg_program *ureg,
+ const int *v,
+ unsigned nr )
+{
+ return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32);
}
@@ -791,8 +871,8 @@ ureg_insn(struct ureg_program *ureg,
unsigned i;
boolean saturate;
boolean predicate;
- boolean negate;
- unsigned swizzle[4];
+ boolean negate = FALSE;
+ unsigned swizzle[4] = { 0 };
saturate = nr_dst ? dst[0].Saturate : FALSE;
predicate = nr_dst ? dst[0].Predicate : FALSE;
@@ -838,8 +918,8 @@ ureg_tex_insn(struct ureg_program *ureg,
unsigned i;
boolean saturate;
boolean predicate;
- boolean negate;
- unsigned swizzle[4];
+ boolean negate = FALSE;
+ unsigned swizzle[4] = { 0 };
saturate = nr_dst ? dst[0].Saturate : FALSE;
predicate = nr_dst ? dst[0].Predicate : FALSE;
@@ -955,21 +1035,23 @@ static void emit_decl_range( struct ureg_program *ureg,
out[1].decl_range.Last = first + count - 1;
}
-static void emit_immediate( struct ureg_program *ureg,
- const float *v )
+static void
+emit_immediate( struct ureg_program *ureg,
+ const unsigned *v,
+ unsigned type )
{
union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );
out[0].value = 0;
out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
out[0].imm.NrTokens = 5;
- out[0].imm.DataType = TGSI_IMM_FLOAT32;
+ out[0].imm.DataType = type;
out[0].imm.Padding = 0;
- out[1].imm_data.Float = v[0];
- out[2].imm_data.Float = v[1];
- out[3].imm_data.Float = v[2];
- out[4].imm_data.Float = v[3];
+ out[1].imm_data.Uint = v[0];
+ out[2].imm_data.Uint = v[1];
+ out[3].imm_data.Uint = v[2];
+ out[4].imm_data.Uint = v[3];
}
@@ -1003,6 +1085,15 @@ static void emit_decls( struct ureg_program *ureg )
}
}
+ for (i = 0; i < ureg->nr_system_values; i++) {
+ emit_decl(ureg,
+ TGSI_FILE_SYSTEM_VALUE,
+ ureg->system_value[i].index,
+ ureg->system_value[i].semantic_name,
+ ureg->system_value[i].semantic_index,
+ TGSI_INTERPOLATE_CONSTANT);
+ }
+
for (i = 0; i < ureg->nr_outputs; i++) {
emit_decl( ureg,
TGSI_FILE_OUTPUT,
@@ -1055,7 +1146,8 @@ static void emit_decls( struct ureg_program *ureg )
for (i = 0; i < ureg->nr_immediates; i++) {
emit_immediate( ureg,
- ureg->immediate[i].v );
+ ureg->immediate[i].value.u,
+ ureg->immediate[i].type );
}
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index 7e3e7bcf1d..38e2fd8d0a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -137,6 +137,12 @@ struct ureg_src
ureg_DECL_gs_input(struct ureg_program *,
unsigned index);
+struct ureg_src
+ureg_DECL_system_value(struct ureg_program *,
+ unsigned index,
+ unsigned semantic_name,
+ unsigned semantic_index);
+
struct ureg_dst
ureg_DECL_output( struct ureg_program *,
unsigned semantic_name,
@@ -148,6 +154,16 @@ ureg_DECL_immediate( struct ureg_program *,
unsigned nr );
struct ureg_src
+ureg_DECL_immediate_uint( struct ureg_program *,
+ const unsigned *v,
+ unsigned nr );
+
+struct ureg_src
+ureg_DECL_immediate_int( struct ureg_program *,
+ const int *v,
+ unsigned nr );
+
+struct ureg_src
ureg_DECL_constant( struct ureg_program *,
unsigned index );
@@ -221,6 +237,90 @@ ureg_imm1f( struct ureg_program *ureg,
return ureg_DECL_immediate( ureg, v, 1 );
}
+static INLINE struct ureg_src
+ureg_imm4u( struct ureg_program *ureg,
+ unsigned a, unsigned b,
+ unsigned c, unsigned d)
+{
+ unsigned v[4];
+ v[0] = a;
+ v[1] = b;
+ v[2] = c;
+ v[3] = d;
+ return ureg_DECL_immediate_uint( ureg, v, 4 );
+}
+
+static INLINE struct ureg_src
+ureg_imm3u( struct ureg_program *ureg,
+ unsigned a, unsigned b,
+ unsigned c)
+{
+ unsigned v[3];
+ v[0] = a;
+ v[1] = b;
+ v[2] = c;
+ return ureg_DECL_immediate_uint( ureg, v, 3 );
+}
+
+static INLINE struct ureg_src
+ureg_imm2u( struct ureg_program *ureg,
+ unsigned a, unsigned b)
+{
+ unsigned v[2];
+ v[0] = a;
+ v[1] = b;
+ return ureg_DECL_immediate_uint( ureg, v, 2 );
+}
+
+static INLINE struct ureg_src
+ureg_imm1u( struct ureg_program *ureg,
+ unsigned a)
+{
+ return ureg_DECL_immediate_uint( ureg, &a, 1 );
+}
+
+static INLINE struct ureg_src
+ureg_imm4i( struct ureg_program *ureg,
+ int a, int b,
+ int c, int d)
+{
+ int v[4];
+ v[0] = a;
+ v[1] = b;
+ v[2] = c;
+ v[3] = d;
+ return ureg_DECL_immediate_int( ureg, v, 4 );
+}
+
+static INLINE struct ureg_src
+ureg_imm3i( struct ureg_program *ureg,
+ int a, int b,
+ int c)
+{
+ int v[3];
+ v[0] = a;
+ v[1] = b;
+ v[2] = c;
+ return ureg_DECL_immediate_int( ureg, v, 3 );
+}
+
+static INLINE struct ureg_src
+ureg_imm2i( struct ureg_program *ureg,
+ int a, int b)
+{
+ int v[2];
+ v[0] = a;
+ v[1] = b;
+ return ureg_DECL_immediate_int( ureg, v, 2 );
+}
+
+static INLINE struct ureg_src
+ureg_imm1i( struct ureg_program *ureg,
+ int a)
+{
+ return ureg_DECL_immediate_int( ureg, &a, 1 );
+}
+
/***********************************************************************
* Functions for patching up labels
*/
diff --git a/src/gallium/auxiliary/translate/Makefile b/src/gallium/auxiliary/translate/Makefile
deleted file mode 100644
index 3c82f8ae03..0000000000
--- a/src/gallium/auxiliary/translate/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = translate
-
-C_SOURCES = \
- translate_generic.c \
- translate_sse.c \
- translate.c \
- translate_cache.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript
deleted file mode 100644
index 9553a67537..0000000000
--- a/src/gallium/auxiliary/translate/SConscript
+++ /dev/null
@@ -1,12 +0,0 @@
-Import('*')
-
-translate = env.ConvenienceLibrary(
- target = 'translate',
- source = [
- 'translate_generic.c',
- 'translate_sse.c',
- 'translate.c',
- 'translate_cache.c',
- ])
-
-auxiliaries.insert(0, translate)
diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h
index 34526eb061..54ed2c1a4b 100644
--- a/src/gallium/auxiliary/translate/translate.h
+++ b/src/gallium/auxiliary/translate/translate.h
@@ -44,12 +44,19 @@
#include "pipe/p_format.h"
#include "pipe/p_state.h"
+enum translate_element_type {
+ TRANSLATE_ELEMENT_NORMAL,
+ TRANSLATE_ELEMENT_INSTANCE_ID
+};
+
struct translate_element
{
+ enum translate_element_type type;
enum pipe_format input_format;
enum pipe_format output_format;
unsigned input_buffer:8;
unsigned input_offset:24;
+ unsigned instance_divisor;
unsigned output_offset;
};
@@ -74,11 +81,13 @@ struct translate {
void (PIPE_CDECL *run_elts)( struct translate *,
const unsigned *elts,
unsigned count,
+ unsigned instance_id,
void *output_buffer);
void (PIPE_CDECL *run)( struct translate *,
unsigned start,
unsigned count,
+ unsigned instance_id,
void *output_buffer);
};
@@ -103,8 +112,13 @@ static INLINE int translate_keysize( const struct translate_key *key )
static INLINE int translate_key_compare( const struct translate_key *a,
const struct translate_key *b )
{
- int keysize = translate_keysize(a);
- return memcmp(a, b, keysize);
+ int keysize_a = translate_keysize(a);
+ int keysize_b = translate_keysize(b);
+
+ if (keysize_a != keysize_b) {
+ return keysize_a - keysize_b;
+ }
+ return memcmp(a, b, keysize_a);
}
diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c
index 266e7ee81e..24727d4988 100644
--- a/src/gallium/auxiliary/translate/translate_generic.c
+++ b/src/gallium/auxiliary/translate/translate_generic.c
@@ -46,9 +46,12 @@ struct translate_generic {
struct translate translate;
struct {
+ enum translate_element_type type;
+
fetch_func fetch;
unsigned buffer;
unsigned input_offset;
+ unsigned instance_divisor;
emit_func emit;
unsigned output_offset;
@@ -568,6 +571,7 @@ static emit_func get_emit_func( enum pipe_format format )
static void PIPE_CDECL generic_run_elts( struct translate *translate,
const unsigned *elts,
unsigned count,
+ unsigned instance_id,
void *output_buffer )
{
struct translate_generic *tg = translate_generic(translate);
@@ -583,13 +587,20 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
for (attr = 0; attr < nr_attrs; attr++) {
float data[4];
-
- const char *src = (tg->attrib[attr].input_ptr +
- tg->attrib[attr].input_stride * elt);
+ const char *src;
char *dst = (vert +
tg->attrib[attr].output_offset);
+ if (tg->attrib[attr].instance_divisor) {
+ src = tg->attrib[attr].input_ptr +
+ tg->attrib[attr].input_stride *
+ (instance_id / tg->attrib[attr].instance_divisor);
+ } else {
+ src = tg->attrib[attr].input_ptr +
+ tg->attrib[attr].input_stride * elt;
+ }
+
tg->attrib[attr].fetch( src, data );
if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n",
@@ -607,6 +618,7 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate,
static void PIPE_CDECL generic_run( struct translate *translate,
unsigned start,
unsigned count,
+ unsigned instance_id,
void *output_buffer )
{
struct translate_generic *tg = translate_generic(translate);
@@ -623,13 +635,25 @@ static void PIPE_CDECL generic_run( struct translate *translate,
for (attr = 0; attr < nr_attrs; attr++) {
float data[4];
- const char *src = (tg->attrib[attr].input_ptr +
- tg->attrib[attr].input_stride * elt);
-
char *dst = (vert +
tg->attrib[attr].output_offset);
- tg->attrib[attr].fetch( src, data );
+ if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
+ const char *src;
+
+ if (tg->attrib[attr].instance_divisor) {
+ src = tg->attrib[attr].input_ptr +
+ tg->attrib[attr].input_stride *
+ (instance_id / tg->attrib[attr].instance_divisor);
+ } else {
+ src = tg->attrib[attr].input_ptr +
+ tg->attrib[attr].input_stride * elt;
+ }
+
+ tg->attrib[attr].fetch( src, data );
+ } else {
+ data[0] = (float)instance_id;
+ }
if (0) debug_printf("vert %d attr %d: %f %f %f %f\n",
i, attr, data[0], data[1], data[2], data[3]);
@@ -683,10 +707,12 @@ struct translate *translate_generic_create( const struct translate_key *key )
tg->translate.run = generic_run;
for (i = 0; i < key->nr_elements; i++) {
+ tg->attrib[i].type = key->element[i].type;
tg->attrib[i].fetch = get_fetch_func(key->element[i].input_format);
tg->attrib[i].buffer = key->element[i].input_buffer;
tg->attrib[i].input_offset = key->element[i].input_offset;
+ tg->attrib[i].instance_divisor = key->element[i].instance_divisor;
tg->attrib[i].emit = get_emit_func(key->element[i].output_format);
tg->attrib[i].output_offset = key->element[i].output_offset;
diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c
index b62db8d8f3..c13e742738 100644
--- a/src/gallium/auxiliary/translate/translate_sse.c
+++ b/src/gallium/auxiliary/translate/translate_sse.c
@@ -49,19 +49,29 @@
typedef void (PIPE_CDECL *run_func)( struct translate *translate,
unsigned start,
unsigned count,
- void *output_buffer );
+ unsigned instance_id,
+ void *output_buffer);
typedef void (PIPE_CDECL *run_elts_func)( struct translate *translate,
const unsigned *elts,
unsigned count,
- void *output_buffer );
+ unsigned instance_id,
+ void *output_buffer);
struct translate_buffer {
const void *base_ptr;
unsigned stride;
- void *ptr; /* updated per vertex */
};
+struct translate_buffer_varient {
+ unsigned buffer_index;
+ unsigned instance_divisor;
+ void *ptr; /* updated either per vertex or per instance */
+};
+
+
+#define ELEMENT_BUFFER_INSTANCE_ID 1001
+
struct translate_sse {
struct translate translate;
@@ -81,6 +91,16 @@ struct translate_sse {
struct translate_buffer buffer[PIPE_MAX_ATTRIBS];
unsigned nr_buffers;
+ /* Multiple buffer varients can map to a single buffer. */
+ struct translate_buffer_varient buffer_varient[PIPE_MAX_ATTRIBS];
+ unsigned nr_buffer_varients;
+
+ /* Multiple elements can map to a single buffer varient. */
+ unsigned element_to_buffer_varient[PIPE_MAX_ATTRIBS];
+
+ boolean use_instancing;
+ unsigned instance_id;
+
run_func gen_run;
run_elts_func gen_run_elts;
@@ -359,32 +379,61 @@ static boolean init_inputs( struct translate_sse *p,
boolean linear )
{
unsigned i;
- if (linear) {
- for (i = 0; i < p->nr_buffers; i++) {
+ struct x86_reg instance_id = x86_make_disp(p->machine_EDX,
+ get_offset(p, &p->instance_id));
+
+ for (i = 0; i < p->nr_buffer_varients; i++) {
+ struct translate_buffer_varient *varient = &p->buffer_varient[i];
+ struct translate_buffer *buffer = &p->buffer[varient->buffer_index];
+
+ if (linear || varient->instance_divisor) {
struct x86_reg buf_stride = x86_make_disp(p->machine_EDX,
- get_offset(p, &p->buffer[i].stride));
+ get_offset(p, &buffer->stride));
struct x86_reg buf_ptr = x86_make_disp(p->machine_EDX,
- get_offset(p, &p->buffer[i].ptr));
+ get_offset(p, &varient->ptr));
struct x86_reg buf_base_ptr = x86_make_disp(p->machine_EDX,
- get_offset(p, &p->buffer[i].base_ptr));
+ get_offset(p, &buffer->base_ptr));
struct x86_reg elt = p->idx_EBX;
- struct x86_reg tmp = p->tmp_EAX;
-
+ struct x86_reg tmp_EAX = p->tmp_EAX;
/* Calculate pointer to first attrib:
+ * base_ptr + stride * index, where index depends on instance divisor
*/
- x86_mov(p->func, tmp, buf_stride);
- x86_imul(p->func, tmp, elt);
- x86_add(p->func, tmp, buf_base_ptr);
+ if (varient->instance_divisor) {
+ /* Our index is instance ID divided by instance divisor.
+ */
+ x86_mov(p->func, tmp_EAX, instance_id);
+
+ if (varient->instance_divisor != 1) {
+ struct x86_reg tmp_EDX = p->machine_EDX;
+ struct x86_reg tmp_ECX = p->outbuf_ECX;
+
+ /* TODO: Add x86_shr() to rtasm and use it whenever
+ * instance divisor is power of two.
+ */
+
+ x86_push(p->func, tmp_EDX);
+ x86_push(p->func, tmp_ECX);
+ x86_xor(p->func, tmp_EDX, tmp_EDX);
+ x86_mov_reg_imm(p->func, tmp_ECX, varient->instance_divisor);
+ x86_div(p->func, tmp_ECX); /* EAX = EDX:EAX / ECX */
+ x86_pop(p->func, tmp_ECX);
+ x86_pop(p->func, tmp_EDX);
+ }
+ } else {
+ x86_mov(p->func, tmp_EAX, elt);
+ }
+ x86_imul(p->func, tmp_EAX, buf_stride);
+ x86_add(p->func, tmp_EAX, buf_base_ptr);
/* In the linear case, keep the buffer pointer instead of the
* index number.
*/
- if (p->nr_buffers == 1)
- x86_mov( p->func, elt, tmp );
+ if (linear && p->nr_buffer_varients == 1)
+ x86_mov(p->func, elt, tmp_EAX);
else
- x86_mov( p->func, buf_ptr, tmp );
+ x86_mov(p->func, buf_ptr, tmp_EAX);
}
}
@@ -394,31 +443,36 @@ static boolean init_inputs( struct translate_sse *p,
static struct x86_reg get_buffer_ptr( struct translate_sse *p,
boolean linear,
- unsigned buf_idx,
+ unsigned var_idx,
struct x86_reg elt )
{
- if (linear && p->nr_buffers == 1) {
+ if (var_idx == ELEMENT_BUFFER_INSTANCE_ID) {
+ return x86_make_disp(p->machine_EDX,
+ get_offset(p, &p->instance_id));
+ }
+ if (linear && p->nr_buffer_varients == 1) {
return p->idx_EBX;
}
- else if (linear) {
+ else if (linear || p->buffer_varient[var_idx].instance_divisor) {
struct x86_reg ptr = p->tmp_EAX;
struct x86_reg buf_ptr =
x86_make_disp(p->machine_EDX,
- get_offset(p, &p->buffer[buf_idx].ptr));
+ get_offset(p, &p->buffer_varient[var_idx].ptr));
x86_mov(p->func, ptr, buf_ptr);
return ptr;
}
else {
struct x86_reg ptr = p->tmp_EAX;
+ const struct translate_buffer_varient *varient = &p->buffer_varient[var_idx];
struct x86_reg buf_stride =
x86_make_disp(p->machine_EDX,
- get_offset(p, &p->buffer[buf_idx].stride));
+ get_offset(p, &p->buffer[varient->buffer_index].stride));
struct x86_reg buf_base_ptr =
x86_make_disp(p->machine_EDX,
- get_offset(p, &p->buffer[buf_idx].base_ptr));
+ get_offset(p, &p->buffer[varient->buffer_index].base_ptr));
@@ -436,28 +490,33 @@ static struct x86_reg get_buffer_ptr( struct translate_sse *p,
static boolean incr_inputs( struct translate_sse *p,
boolean linear )
{
- if (linear && p->nr_buffers == 1) {
+ if (linear && p->nr_buffer_varients == 1) {
struct x86_reg stride = x86_make_disp(p->machine_EDX,
get_offset(p, &p->buffer[0].stride));
- x86_add(p->func, p->idx_EBX, stride);
- sse_prefetchnta(p->func, x86_make_disp(p->idx_EBX, 192));
+ if (p->buffer_varient[0].instance_divisor == 0) {
+ x86_add(p->func, p->idx_EBX, stride);
+ sse_prefetchnta(p->func, x86_make_disp(p->idx_EBX, 192));
+ }
}
else if (linear) {
unsigned i;
/* Is this worthwhile??
*/
- for (i = 0; i < p->nr_buffers; i++) {
+ for (i = 0; i < p->nr_buffer_varients; i++) {
+ struct translate_buffer_varient *varient = &p->buffer_varient[i];
struct x86_reg buf_ptr = x86_make_disp(p->machine_EDX,
- get_offset(p, &p->buffer[i].ptr));
+ get_offset(p, &varient->ptr));
struct x86_reg buf_stride = x86_make_disp(p->machine_EDX,
- get_offset(p, &p->buffer[i].stride));
+ get_offset(p, &p->buffer[varient->buffer_index].stride));
- x86_mov(p->func, p->tmp_EAX, buf_ptr);
- x86_add(p->func, p->tmp_EAX, buf_stride);
- if (i == 0) sse_prefetchnta(p->func, x86_make_disp(p->tmp_EAX, 192));
- x86_mov(p->func, buf_ptr, p->tmp_EAX);
+ if (varient->instance_divisor == 0) {
+ x86_mov(p->func, p->tmp_EAX, buf_ptr);
+ x86_add(p->func, p->tmp_EAX, buf_stride);
+ if (i == 0) sse_prefetchnta(p->func, x86_make_disp(p->tmp_EAX, 192));
+ x86_mov(p->func, buf_ptr, p->tmp_EAX);
+ }
}
}
else {
@@ -514,7 +573,18 @@ static boolean build_vertex_emit( struct translate_sse *p,
x86_mov(p->func, p->machine_EDX, x86_fn_arg(p->func, 1));
x86_mov(p->func, p->idx_EBX, x86_fn_arg(p->func, 2));
x86_mov(p->func, p->count_ESI, x86_fn_arg(p->func, 3));
- x86_mov(p->func, p->outbuf_ECX, x86_fn_arg(p->func, 4));
+ x86_mov(p->func, p->outbuf_ECX, x86_fn_arg(p->func, 5));
+
+ /* Load instance ID.
+ */
+ if (p->use_instancing) {
+ x86_mov(p->func,
+ p->tmp_EAX,
+ x86_fn_arg(p->func, 4));
+ x86_mov(p->func,
+ x86_make_disp(p->machine_EDX, get_offset(p, &p->instance_id)),
+ p->tmp_EAX);
+ }
/* Get vertex count, compare to zero
*/
@@ -531,17 +601,18 @@ static boolean build_vertex_emit( struct translate_sse *p,
label = x86_get_label(p->func);
{
struct x86_reg elt = linear ? p->idx_EBX : x86_deref(p->idx_EBX);
- int last_vb = -1;
+ int last_varient = -1;
struct x86_reg vb;
for (j = 0; j < p->translate.key.nr_elements; j++) {
const struct translate_element *a = &p->translate.key.element[j];
+ unsigned varient = p->element_to_buffer_varient[j];
/* Figure out source pointer address:
*/
- if (a->input_buffer != last_vb) {
- last_vb = a->input_buffer;
- vb = get_buffer_ptr(p, linear, a->input_buffer, elt);
+ if (varient != last_varient) {
+ last_varient = varient;
+ vb = get_buffer_ptr(p, linear, varient, elt);
}
if (!translate_attr( p, a,
@@ -624,6 +695,7 @@ static void translate_sse_release( struct translate *translate )
static void PIPE_CDECL translate_sse_run_elts( struct translate *translate,
const unsigned *elts,
unsigned count,
+ unsigned instance_id,
void *output_buffer )
{
struct translate_sse *p = (struct translate_sse *)translate;
@@ -631,12 +703,14 @@ static void PIPE_CDECL translate_sse_run_elts( struct translate *translate,
p->gen_run_elts( translate,
elts,
count,
- output_buffer );
+ instance_id,
+ output_buffer);
}
static void PIPE_CDECL translate_sse_run( struct translate *translate,
unsigned start,
unsigned count,
+ unsigned instance_id,
void *output_buffer )
{
struct translate_sse *p = (struct translate_sse *)translate;
@@ -644,7 +718,8 @@ static void PIPE_CDECL translate_sse_run( struct translate *translate,
p->gen_run( translate,
start,
count,
- output_buffer );
+ instance_id,
+ output_buffer);
}
@@ -666,8 +741,37 @@ struct translate *translate_sse2_create( const struct translate_key *key )
p->translate.run_elts = translate_sse_run_elts;
p->translate.run = translate_sse_run;
- for (i = 0; i < key->nr_elements; i++)
- p->nr_buffers = MAX2( p->nr_buffers, key->element[i].input_buffer + 1 );
+ for (i = 0; i < key->nr_elements; i++) {
+ if (key->element[i].type == TRANSLATE_ELEMENT_NORMAL) {
+ unsigned j;
+
+ p->nr_buffers = MAX2(p->nr_buffers, key->element[i].input_buffer + 1);
+
+ if (key->element[i].instance_divisor) {
+ p->use_instancing = TRUE;
+ }
+
+ /*
+ * Map vertex element to vertex buffer varient.
+ */
+ for (j = 0; j < p->nr_buffer_varients; j++) {
+ if (p->buffer_varient[j].buffer_index == key->element[i].input_buffer &&
+ p->buffer_varient[j].instance_divisor == key->element[i].instance_divisor) {
+ break;
+ }
+ }
+ if (j == p->nr_buffer_varients) {
+ p->buffer_varient[j].buffer_index = key->element[i].input_buffer;
+ p->buffer_varient[j].instance_divisor = key->element[i].instance_divisor;
+ p->nr_buffer_varients++;
+ }
+ p->element_to_buffer_varient[i] = j;
+ } else {
+ assert(key->element[i].type == TRANSLATE_ELEMENT_INSTANCE_ID);
+
+ p->element_to_buffer_varient[i] = ELEMENT_BUFFER_INSTANCE_ID;
+ }
+ }
if (0) debug_printf("nr_buffers: %d\n", p->nr_buffers);
diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile
deleted file mode 100644
index 3ed90fd1b7..0000000000
--- a/src/gallium/auxiliary/util/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = util
-
-C_SOURCES = \
- u_debug.c \
- u_debug_dump.c \
- u_debug_symbol.c \
- u_debug_stack.c \
- u_blit.c \
- u_blitter.c \
- u_cache.c \
- u_cpu_detect.c \
- u_dl.c \
- u_draw_quad.c \
- u_format.c \
- u_format_access.c \
- u_format_table.c \
- u_gen_mipmap.c \
- u_handle_table.c \
- u_hash_table.c \
- u_hash.c \
- u_keymap.c \
- u_linear.c \
- u_network.c \
- u_math.c \
- u_mm.c \
- u_rect.c \
- u_simple_shaders.c \
- u_snprintf.c \
- u_stream_stdc.c \
- u_stream_wd.c \
- u_surface.c \
- u_texture.c \
- u_tile.c \
- u_time.c \
- u_timed_winsys.c \
- u_upload_mgr.c \
- u_simple_screen.c
-
-include ../../Makefile.template
-
-u_format_table.c: u_format_table.py u_format_parse.py u_format.csv
- python u_format_table.py u_format.csv > $@
-
-u_format_access.c: u_format_access.py u_format_parse.py u_format.csv
- python u_format_access.py u_format.csv > $@
diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript
deleted file mode 100644
index 2a546d19dc..0000000000
--- a/src/gallium/auxiliary/util/SConscript
+++ /dev/null
@@ -1,61 +0,0 @@
-Import('*')
-
-env.Clone()
-
-env.Append(CPPPATH = ['.'])
-
-env.CodeGenerate(
- target = 'u_format_table.c',
- script = 'u_format_table.py',
- source = ['u_format.csv'],
- command = 'python $SCRIPT $SOURCE > $TARGET'
-)
-
-env.CodeGenerate(
- target = 'u_format_access.c',
- script = 'u_format_access.py',
- source = ['u_format.csv'],
- command = 'python $SCRIPT $SOURCE > $TARGET'
-)
-
-util = env.ConvenienceLibrary(
- target = 'util',
- source = [
- 'u_bitmask.c',
- 'u_blit.c',
- 'u_blitter.c',
- 'u_cache.c',
- 'u_cpu_detect.c',
- 'u_debug.c',
- 'u_debug_dump.c',
- 'u_debug_memory.c',
- 'u_debug_stack.c',
- 'u_debug_symbol.c',
- 'u_dl.c',
- 'u_draw_quad.c',
- 'u_format.c',
- 'u_format_access.c',
- 'u_format_table.c',
- 'u_gen_mipmap.c',
- 'u_handle_table.c',
- 'u_hash.c',
- 'u_hash_table.c',
- 'u_keymap.c',
- 'u_network.c',
- 'u_math.c',
- 'u_mm.c',
- 'u_rect.c',
- 'u_simple_shaders.c',
- 'u_snprintf.c',
- 'u_stream_stdc.c',
- 'u_stream_wd.c',
- 'u_surface.c',
- 'u_texture.c',
- 'u_tile.c',
- 'u_time.c',
- 'u_timed_winsys.c',
- 'u_upload_mgr.c',
- 'u_simple_screen.c',
- ])
-
-auxiliaries.insert(0, util)
diff --git a/src/gallium/auxiliary/util/u_bitmask.c b/src/gallium/auxiliary/util/u_bitmask.c
index 77587c07ec..23c93a3ebc 100644
--- a/src/gallium/auxiliary/util/u_bitmask.c
+++ b/src/gallium/auxiliary/util/u_bitmask.c
@@ -97,12 +97,12 @@ util_bitmask_resize(struct util_bitmask *bm,
if(!minimum_size)
return FALSE;
- if(bm->size > minimum_size)
+ if(bm->size >= minimum_size)
return TRUE;
assert(bm->size % UTIL_BITMASK_BITS_PER_WORD == 0);
new_size = bm->size;
- while(!(new_size > minimum_size)) {
+ while(new_size < minimum_size) {
new_size *= 2;
/* Check integer overflow */
if(new_size < bm->size)
@@ -136,7 +136,7 @@ util_bitmask_filled_set(struct util_bitmask *bm,
unsigned index)
{
assert(bm->filled <= bm->size);
- assert(index <= bm->size);
+ assert(index < bm->size);
if(index == bm->filled) {
++bm->filled;
@@ -149,7 +149,7 @@ util_bitmask_filled_unset(struct util_bitmask *bm,
unsigned index)
{
assert(bm->filled <= bm->size);
- assert(index <= bm->size);
+ assert(index < bm->size);
if(index < bm->filled)
bm->filled = index;
@@ -182,7 +182,7 @@ util_bitmask_add(struct util_bitmask *bm)
mask = 1;
}
found:
-
+
/* grow the bitmask if necessary */
if(!util_bitmask_resize(bm, bm->filled))
return UTIL_BITMASK_INVALID_INDEX;
@@ -198,9 +198,9 @@ unsigned
util_bitmask_set(struct util_bitmask *bm,
unsigned index)
{
- unsigned word = index / UTIL_BITMASK_BITS_PER_WORD;
- unsigned bit = index % UTIL_BITMASK_BITS_PER_WORD;
- util_bitmask_word mask = 1 << bit;
+ unsigned word;
+ unsigned bit;
+ util_bitmask_word mask;
assert(bm);
@@ -208,6 +208,10 @@ util_bitmask_set(struct util_bitmask *bm,
if(!util_bitmask_resize(bm, index))
return UTIL_BITMASK_INVALID_INDEX;
+ word = index / UTIL_BITMASK_BITS_PER_WORD;
+ bit = index % UTIL_BITMASK_BITS_PER_WORD;
+ mask = 1 << bit;
+
bm->words[word] |= mask;
util_bitmask_filled_set(bm, index);
@@ -220,15 +224,19 @@ void
util_bitmask_clear(struct util_bitmask *bm,
unsigned index)
{
- unsigned word = index / UTIL_BITMASK_BITS_PER_WORD;
- unsigned bit = index % UTIL_BITMASK_BITS_PER_WORD;
- util_bitmask_word mask = 1 << bit;
+ unsigned word;
+ unsigned bit;
+ util_bitmask_word mask;
assert(bm);
if(index >= bm->size)
return;
+ word = index / UTIL_BITMASK_BITS_PER_WORD;
+ bit = index % UTIL_BITMASK_BITS_PER_WORD;
+ mask = 1 << bit;
+
bm->words[word] &= ~mask;
util_bitmask_filled_unset(bm, index);
@@ -250,7 +258,7 @@ util_bitmask_get(struct util_bitmask *bm,
return TRUE;
}
- if(index > bm->size)
+ if(index >= bm->size)
return FALSE;
if(bm->words[word] & mask) {
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 1f794d39a1..249a0375fc 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -48,6 +48,8 @@
#include "util/u_simple_shaders.h"
#include "util/u_texture.h"
+#define INVALID_PTR ((void*)~0)
+
struct blitter_context_priv
{
struct blitter_context blitter;
@@ -110,6 +112,11 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->pipe = pipe;
/* init state objects for them to be considered invalid */
+ ctx->blitter.saved_blend_state = INVALID_PTR;
+ ctx->blitter.saved_dsa_state = INVALID_PTR;
+ ctx->blitter.saved_rs_state = INVALID_PTR;
+ ctx->blitter.saved_fs = INVALID_PTR;
+ ctx->blitter.saved_vs = INVALID_PTR;
ctx->blitter.saved_fb_state.nr_cbufs = ~0;
ctx->blitter.saved_num_textures = ~0;
ctx->blitter.saved_num_sampler_states = ~0;
@@ -156,6 +163,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
rs_state.cull_mode = PIPE_WINDING_NONE;
rs_state.bypass_vs_clip_and_viewport = 1;
rs_state.gl_rasterization_rules = 1;
+ rs_state.flatshade = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
/* fragment shaders are created on-demand */
@@ -234,11 +242,11 @@ void util_blitter_destroy(struct blitter_context *blitter)
static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
{
/* make sure these CSOs have been saved */
- assert(ctx->blitter.saved_blend_state &&
- ctx->blitter.saved_dsa_state &&
- ctx->blitter.saved_rs_state &&
- ctx->blitter.saved_fs &&
- ctx->blitter.saved_vs);
+ assert(ctx->blitter.saved_blend_state != INVALID_PTR &&
+ ctx->blitter.saved_dsa_state != INVALID_PTR &&
+ ctx->blitter.saved_rs_state != INVALID_PTR &&
+ ctx->blitter.saved_fs != INVALID_PTR &&
+ ctx->blitter.saved_vs != INVALID_PTR);
}
static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
@@ -252,11 +260,11 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
pipe->bind_fs_state(pipe, ctx->blitter.saved_fs);
pipe->bind_vs_state(pipe, ctx->blitter.saved_vs);
- ctx->blitter.saved_blend_state = 0;
- ctx->blitter.saved_dsa_state = 0;
- ctx->blitter.saved_rs_state = 0;
- ctx->blitter.saved_fs = 0;
- ctx->blitter.saved_vs = 0;
+ ctx->blitter.saved_blend_state = INVALID_PTR;
+ ctx->blitter.saved_dsa_state = INVALID_PTR;
+ ctx->blitter.saved_rs_state = INVALID_PTR;
+ ctx->blitter.saved_fs = INVALID_PTR;
+ ctx->blitter.saved_vs = INVALID_PTR;
/* restore the state objects which are required to be saved before copy/fill
*/
@@ -371,9 +379,16 @@ static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
float t1 = y1 / (float)surf->height;
float s2 = x2 / (float)surf->width;
float t2 = y2 / (float)surf->height;
- const float st[4][2] = {
- {s1, t1}, {s2, t1}, {s2, t2}, {s1, t2}
- };
+ float st[4][2];
+
+ st[0][0] = s1;
+ st[0][1] = t1;
+ st[1][0] = s2;
+ st[1][1] = t1;
+ st[2][0] = s2;
+ st[2][1] = t2;
+ st[3][0] = s1;
+ st[3][1] = t2;
util_map_texcoords2d_onto_cubemap(surf->face,
/* pointer, stride in floats */
@@ -560,45 +575,29 @@ void util_blitter_clear(struct blitter_context *blitter,
blitter_restore_CSOs(ctx);
}
-void util_blitter_copy(struct blitter_context *blitter,
- struct pipe_surface *dst,
- unsigned dstx, unsigned dsty,
- struct pipe_surface *src,
- unsigned srcx, unsigned srcy,
- unsigned width, unsigned height,
- boolean ignore_stencil)
+static boolean
+is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2,
+ unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2)
+{
+ if (sx1 >= dx2 || sx2 <= dx1 || sy1 >= dy2 || sy2 <= dy1) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+static void util_blitter_do_copy(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height,
+ boolean is_depth)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb_state;
- boolean is_stencil, is_depth;
- unsigned dst_tex_usage;
-
- /* give up if textures are not set */
- assert(dst->texture && src->texture);
- if (!dst->texture || !src->texture)
- return;
-
- is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
- is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0;
- dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
- PIPE_TEXTURE_USAGE_RENDER_TARGET;
- /* check if we can sample from and render to the surfaces */
- /* (assuming copying a stencil buffer is not possible) */
- if ((!ignore_stencil && is_stencil) ||
- !screen->is_format_supported(screen, dst->format, dst->texture->target,
- dst_tex_usage, 0) ||
- !screen->is_format_supported(screen, src->format, src->texture->target,
- PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
- util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy,
- width, height);
- return;
- }
-
- /* check whether the states are properly saved */
- blitter_check_saved_CSOs(ctx);
assert(blitter->saved_fb_state.nr_cbufs != ~0);
assert(blitter->saved_num_textures != ~0);
assert(blitter->saved_num_sampler_states != ~0);
@@ -656,6 +655,108 @@ void util_blitter_copy(struct blitter_context *blitter,
blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
blitter_draw_quad(ctx);
+
+}
+
+static void util_blitter_overlap_copy(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_screen *screen = pipe->screen;
+
+ struct pipe_texture texTemp;
+ struct pipe_texture *texture;
+ struct pipe_surface *tex_surf;
+
+ /* check whether the states are properly saved */
+ blitter_check_saved_CSOs(ctx);
+
+ memset(&texTemp, 0, sizeof(texTemp));
+ texTemp.target = PIPE_TEXTURE_2D;
+ texTemp.format = dst->texture->format; /* XXX verify supported by driver! */
+ texTemp.last_level = 0;
+ texTemp.width0 = width;
+ texTemp.height0 = height;
+ texTemp.depth0 = 1;
+
+ texture = screen->texture_create(screen, &texTemp);
+ if (!texture)
+ return;
+
+ tex_surf = screen->get_tex_surface(screen, texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ /* blit from the src to the temp */
+ util_blitter_do_copy(blitter, tex_surf, 0, 0,
+ src, srcx, srcy,
+ width, height,
+ FALSE);
+ util_blitter_do_copy(blitter, dst, dstx, dsty,
+ tex_surf, 0, 0,
+ width, height,
+ FALSE);
+ pipe_surface_reference(&tex_surf, NULL);
+ pipe_texture_reference(&texture, NULL);
+ blitter_restore_CSOs(ctx);
+}
+
+void util_blitter_copy(struct blitter_context *blitter,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height,
+ boolean ignore_stencil)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ boolean is_stencil, is_depth;
+ unsigned dst_tex_usage;
+
+ /* give up if textures are not set */
+ assert(dst->texture && src->texture);
+ if (!dst->texture || !src->texture)
+ return;
+
+ if (dst->texture == src->texture) {
+ if (is_overlap(srcx, srcx + width, srcy, srcy + height,
+ dstx, dstx + width, dsty, dsty + height)) {
+ util_blitter_overlap_copy(blitter, dst, dstx, dsty, src, srcx, srcy,
+ width, height);
+ return;
+ }
+ }
+
+ is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
+ is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0;
+ dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+ /* check if we can sample from and render to the surfaces */
+ /* (assuming copying a stencil buffer is not possible) */
+ if ((!ignore_stencil && is_stencil) ||
+ !screen->is_format_supported(screen, dst->format, dst->texture->target,
+ dst_tex_usage, 0) ||
+ !screen->is_format_supported(screen, src->format, src->texture->target,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
+ util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy,
+ width, height);
+ return;
+ }
+
+ /* check whether the states are properly saved */
+ blitter_check_saved_CSOs(ctx);
+ util_blitter_do_copy(blitter,
+ dst, dstx, dsty,
+ src, srcx, srcy,
+ width, height, is_depth);
blitter_restore_CSOs(ctx);
}
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 4e01123fff..9b4e6ca2a7 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -454,7 +454,8 @@ debug_dump_flags(const struct debug_named_value *names,
util_strncat(output, "|", sizeof(output));
else
first = 0;
- util_strncat(output, names->name, sizeof(output));
+ util_strncat(output, names->name, sizeof(output) - 1);
+ output[sizeof(output) - 1] = '\0';
value &= ~names->value;
}
++names;
@@ -467,7 +468,8 @@ debug_dump_flags(const struct debug_named_value *names,
first = 0;
util_snprintf(rest, sizeof(rest), "0x%08lx", value);
- util_strncat(output, rest, sizeof(output));
+ util_strncat(output, rest, sizeof(output) - 1);
+ output[sizeof(output) - 1] = '\0';
}
if(first)
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index abd834c741..facc30a553 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -188,7 +188,7 @@ void _debug_assert_fail(const char *expr,
#ifdef DEBUG
#define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__))
#else
-#define debug_assert(expr) ((void)0)
+#define debug_assert(expr) do { } while (0 && (expr))
#endif
diff --git a/src/gallium/auxiliary/util/u_debug_dump.c b/src/gallium/auxiliary/util/u_debug_dump.c
index 09866880ae..61624d05c0 100644
--- a/src/gallium/auxiliary/util/u_debug_dump.c
+++ b/src/gallium/auxiliary/util/u_debug_dump.c
@@ -255,15 +255,13 @@ DEFINE_DEBUG_DUMP_CONTINUOUS(tex_mipfilter)
static const char *
debug_dump_tex_filter_names[] = {
"PIPE_TEX_FILTER_NEAREST",
- "PIPE_TEX_FILTER_LINEAR",
- "PIPE_TEX_FILTER_ANISO"
+ "PIPE_TEX_FILTER_LINEAR"
};
static const char *
debug_dump_tex_filter_short_names[] = {
"nearest",
- "linear",
- "aniso"
+ "linear"
};
DEFINE_DEBUG_DUMP_CONTINUOUS(tex_filter)
diff --git a/src/gallium/auxiliary/util/u_debug_memory.c b/src/gallium/auxiliary/util/u_debug_memory.c
index 7623cb9398..d6484f4ad5 100644
--- a/src/gallium/auxiliary/util/u_debug_memory.c
+++ b/src/gallium/auxiliary/util/u_debug_memory.c
@@ -297,9 +297,9 @@ debug_memory_end(unsigned long start_no)
if((start_no <= hdr->no && hdr->no < last_no) ||
(last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))) {
- debug_printf("%s:%u:%s: %u bytes at %p not freed\n",
+ debug_printf("%s:%u:%s: %lu bytes at %p not freed\n",
hdr->file, hdr->line, hdr->function,
- hdr->size, ptr);
+ (unsigned long) hdr->size, ptr);
#if DEBUG_MEMORY_STACK
debug_backtrace_dump(hdr->backtrace, DEBUG_MEMORY_STACK);
#endif
@@ -315,8 +315,8 @@ debug_memory_end(unsigned long start_no)
}
if(total_size) {
- debug_printf("Total of %u KB of system memory apparently leaked\n",
- (total_size + 1023)/1024);
+ debug_printf("Total of %lu KB of system memory apparently leaked\n",
+ (unsigned long) (total_size + 1023)/1024);
}
else {
debug_printf("No memory leaks detected.\n");
diff --git a/src/gallium/auxiliary/util/u_dl.h b/src/gallium/auxiliary/util/u_dl.h
index 018b38543b..85296c58af 100644
--- a/src/gallium/auxiliary/util/u_dl.h
+++ b/src/gallium/auxiliary/util/u_dl.h
@@ -30,6 +30,18 @@
#define U_DL_H_
+#include "pipe/p_config.h"
+
+
+#if defined(PIPE_OS_WINDOWS)
+# define UTIL_DL_EXT ".dll"
+#elif defined(PIPE_OS_APPLE)
+# define UTIL_DL_EXT ".dylib"
+#else
+# define UTIL_DL_EXT ".so"
+#endif
+
+
struct util_dl_library;
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index 866b18ff16..9f16b42944 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -76,9 +76,9 @@ PIPE_FORMAT_R8G8_SNORM , array , 1, 1, sn8 , sn8 , , , xy01,
PIPE_FORMAT_R8G8B8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , , xyz1, rgb
PIPE_FORMAT_R8G8B8A8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
PIPE_FORMAT_R8G8B8X8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , xyz1, rgb
-PIPE_FORMAT_B6G5R5_SNORM , arith , 1, 1, sn5 , sn5 , sn6 , , zyx1, rgb
-PIPE_FORMAT_A8B8G8R8_SNORM , arith , 1, 1, sn8 , sn8 , sn8 , sn8 , zyxw, rgb
-PIPE_FORMAT_X8B8G8R8_SNORM , arith , 1, 1, sn8 , sn8 , sn8 , sn8 , zyx1, rgb
+PIPE_FORMAT_B6G5R5_SNORM , arith , 1, 1, sn5 , sn5 , sn6 , , xyz1, rgb
+PIPE_FORMAT_A8B8G8R8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , wzyx, rgb
+PIPE_FORMAT_X8B8G8R8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , wzy1, rgb
PIPE_FORMAT_R8_SSCALED , array , 1, 1, s8 , , , , x001, rgb
PIPE_FORMAT_R8G8_SSCALED , array , 1, 1, s8 , s8 , , , xy01, rgb
PIPE_FORMAT_R8G8B8_SSCALED , array , 1, 1, s8 , s8 , s8 , , xyz1, rgb
@@ -90,14 +90,14 @@ PIPE_FORMAT_R32G32B32_FIXED , array , 1, 1, h32 , h32 , h32 , , xyz1,
PIPE_FORMAT_R32G32B32A32_FIXED , array , 1, 1, h32 , h32 , h32 , h32 , xyzw, rgb
PIPE_FORMAT_L8_SRGB , arith , 1, 1, u8 , , , , xxx1, srgb
PIPE_FORMAT_A8L8_SRGB , arith , 1, 1, u8 , u8 , , , xxxy, srgb
-PIPE_FORMAT_R8G8B8_SRGB , arith , 1, 1, u8 , u8 , u8 , , xyz1, srgb
-PIPE_FORMAT_R8G8B8A8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , xyzw, srgb
-PIPE_FORMAT_R8G8B8X8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , xyz1, srgb
-PIPE_FORMAT_A8R8G8B8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , wxyz, srgb
-PIPE_FORMAT_X8R8G8B8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , 1xyz, srgb
-PIPE_FORMAT_B8G8R8A8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , zyxw, srgb
-PIPE_FORMAT_B8G8R8X8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , zyx1, srgb
-PIPE_FORMAT_X8UB8UG8SR8S_NORM , arith , 1, 1, sn8 , sn8 , un8 , x8 , 1zyx, rgb
+PIPE_FORMAT_R8G8B8_SRGB , array , 1, 1, u8 , u8 , u8 , , xyz1, srgb
+PIPE_FORMAT_R8G8B8A8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , xyzw, srgb
+PIPE_FORMAT_R8G8B8X8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , xyz1, srgb
+PIPE_FORMAT_A8R8G8B8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , yzwx, srgb
+PIPE_FORMAT_X8R8G8B8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , yzw1, srgb
+PIPE_FORMAT_B8G8R8A8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , zyxw, srgb
+PIPE_FORMAT_B8G8R8X8_SRGB , array , 1, 1, u8 , u8 , u8 , u8 , zyx1, srgb
+PIPE_FORMAT_X8UB8UG8SR8S_NORM , array , 1, 1, sn8 , sn8 , un8 , x8 , wzy1, rgb
PIPE_FORMAT_B6UG5SR5S_NORM , arith , 1, 1, sn5 , sn5 , un6 , , xyz1, rgb
PIPE_FORMAT_DXT1_RGB , dxt , 4, 4, x64 , , , , xyz1, rgb
PIPE_FORMAT_DXT1_RGBA , dxt , 4, 4, x64 , , , , xyzw, rgb
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 090183fb17..a558923b2e 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -119,7 +119,7 @@ enum util_format_colorspace {
UTIL_FORMAT_COLORSPACE_RGB = 0,
UTIL_FORMAT_COLORSPACE_SRGB = 1,
UTIL_FORMAT_COLORSPACE_YUV = 2,
- UTIL_FORMAT_COLORSPACE_ZS = 3,
+ UTIL_FORMAT_COLORSPACE_ZS = 3
};
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index 81aeb83cbb..b2969a210a 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -585,13 +585,12 @@ do { \
static INLINE uint32_t util_unsigned_fixed(float value, unsigned frac_bits)
{
- value *= (1<<frac_bits);
- return value < 0 ? 0 : value;
+ return value < 0 ? 0 : (uint32_t)(value * (1<<frac_bits));
}
static INLINE int32_t util_signed_fixed(float value, unsigned frac_bits)
{
- return value * (1<<frac_bits);
+ return (int32_t)(value * (1<<frac_bits));
}
diff --git a/src/gallium/auxiliary/util/u_network.c b/src/gallium/auxiliary/util/u_network.c
index 6269c72e12..87ee0e4768 100644
--- a/src/gallium/auxiliary/util/u_network.c
+++ b/src/gallium/auxiliary/util/u_network.c
@@ -6,7 +6,7 @@
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
# include <winsock2.h>
# include <windows.h>
-#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
# include <sys/socket.h>
# include <netinet/in.h>
# include <unistd.h>
@@ -54,7 +54,7 @@ u_socket_close(int s)
if (s < 0)
return;
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
shutdown(s, SHUT_RDWR);
close(s);
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
@@ -117,7 +117,7 @@ u_socket_connect(const char *hostname, uint16_t port)
if (!host)
return -1;
- memcpy((char *)&sa.sin_addr,host->h_addr,host->h_length);
+ memcpy((char *)&sa.sin_addr,host->h_addr_list[0],host->h_length);
sa.sin_family= host->h_addrtype;
sa.sin_port = htons(port);
@@ -169,7 +169,7 @@ u_socket_listen_on_port(uint16_t portnum)
void
u_socket_block(int s, boolean block)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
int old = fcntl(s, F_GETFL, 0);
if (old == -1)
return;
diff --git a/src/gallium/auxiliary/util/u_network.h b/src/gallium/auxiliary/util/u_network.h
index 0aa898b967..187dcab86e 100644
--- a/src/gallium/auxiliary/util/u_network.h
+++ b/src/gallium/auxiliary/util/u_network.h
@@ -6,7 +6,7 @@
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
# define PIPE_HAVE_SOCKETS
-#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_BSD)
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
# define PIPE_HAVE_SOCKETS
#endif
diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h
index 7434329962..10a874f341 100644
--- a/src/gallium/auxiliary/util/u_prim.h
+++ b/src/gallium/auxiliary/util/u_prim.h
@@ -135,6 +135,39 @@ static INLINE unsigned u_reduced_prim( unsigned pipe_prim )
}
}
+static INLINE unsigned
+u_vertices_per_prim(int primitive)
+{
+ switch(primitive) {
+ case PIPE_PRIM_POINTS:
+ return 1;
+ case PIPE_PRIM_LINES:
+ case PIPE_PRIM_LINE_LOOP:
+ case PIPE_PRIM_LINE_STRIP:
+ return 2;
+ case PIPE_PRIM_TRIANGLES:
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ case PIPE_PRIM_TRIANGLE_FAN:
+ return 3;
+ case PIPE_PRIM_LINES_ADJACENCY:
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ return 4;
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ return 6;
+
+ /* following primitives should never be used
+ * with geometry shaders abd their size is
+ * undefined */
+ case PIPE_PRIM_POLYGON:
+ case PIPE_PRIM_QUADS:
+ case PIPE_PRIM_QUAD_STRIP:
+ default:
+ debug_printf("Unrecognized geometry shader primitive");
+ return 3;
+ }
+}
+
const char *u_prim_name( unsigned pipe_prim );
#endif
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index 298fbacecb..8479161c74 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -41,7 +41,7 @@
/**
* Copy 2D rect from one place to another.
* Position and sizes are in pixels.
- * src_pitch may be negative to do vertical flip of pixels from source.
+ * src_stride may be negative to do vertical flip of pixels from source.
*/
void
util_copy_rect(ubyte * dst,
@@ -54,7 +54,7 @@ util_copy_rect(ubyte * dst,
const ubyte * src,
int src_stride,
unsigned src_x,
- int src_y)
+ unsigned src_y)
{
unsigned i;
int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
@@ -65,10 +65,6 @@ util_copy_rect(ubyte * dst,
assert(blocksize > 0);
assert(blockwidth > 0);
assert(blockheight > 0);
- assert(src_x >= 0);
- assert(src_y >= 0);
- assert(dst_x >= 0);
- assert(dst_y >= 0);
dst_x /= blockwidth;
dst_y /= blockheight;
@@ -113,8 +109,6 @@ util_fill_rect(ubyte * dst,
assert(blocksize > 0);
assert(blockwidth > 0);
assert(blockheight > 0);
- assert(dst_x >= 0);
- assert(dst_y >= 0);
dst_x /= blockwidth;
dst_y /= blockheight;
diff --git a/src/gallium/auxiliary/util/u_rect.h b/src/gallium/auxiliary/util/u_rect.h
index 5e444ffae2..b44d821904 100644
--- a/src/gallium/auxiliary/util/u_rect.h
+++ b/src/gallium/auxiliary/util/u_rect.h
@@ -45,7 +45,7 @@ extern void
util_copy_rect(ubyte * dst, enum pipe_format format,
unsigned dst_stride, unsigned dst_x, unsigned dst_y,
unsigned width, unsigned height, const ubyte * src,
- int src_stride, unsigned src_x, int src_y);
+ int src_stride, unsigned src_x, unsigned src_y);
extern void
util_fill_rect(ubyte * dst, enum pipe_format format,
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 8172ead020..b751e29ab6 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -44,13 +44,15 @@
/**
* Make simple vertex pass-through shader.
+ * \param num_attribs number of attributes to pass through
+ * \param semantic_names array of semantic names for each attribute
+ * \param semantic_indexes array of semantic indexes for each attribute
*/
void *
util_make_vertex_passthrough_shader(struct pipe_context *pipe,
uint num_attribs,
const uint *semantic_names,
const uint *semantic_indexes)
-
{
struct ureg_program *ureg;
uint i;
@@ -78,8 +80,6 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
}
-
-
/**
* Make simple fragment texture shader:
* IMM {0,0,0,1} // (if writemask != 0xf)
@@ -125,6 +125,12 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
return ureg_create_shader_and_destroy( ureg, pipe );
}
+
+/**
+ * Make a simple fragment shader that sets the output color to a color
+ * taken from a texture.
+ * \param tex_target one of PIPE_TEXTURE_x
+ */
void *
util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target )
{
@@ -133,6 +139,7 @@ util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target )
TGSI_WRITEMASK_XYZW );
}
+
/**
* Make a simple fragment texture shader which reads an X component from
* a texture and writes it as depth.
@@ -177,6 +184,7 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
return ureg_create_shader_and_destroy( ureg, pipe );
}
+
/**
* Make simple fragment color pass-through shader.
*/
@@ -186,15 +194,19 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe)
return util_make_fragment_clonecolor_shader(pipe, 1);
}
+
+/**
+ * Make a fragment shader that copies the input color to N output colors.
+ */
void *
util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs)
{
struct ureg_program *ureg;
struct ureg_src src;
- struct ureg_dst dst[8];
+ struct ureg_dst dst[PIPE_MAX_COLOR_BUFS];
int i;
- assert(num_cbufs <= 8);
+ assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
if (ureg == NULL)
diff --git a/src/gallium/auxiliary/util/u_stream_stdc.c b/src/gallium/auxiliary/util/u_stream_stdc.c
index 5cd05b2904..4d976d6dca 100644
--- a/src/gallium/auxiliary/util/u_stream_stdc.c
+++ b/src/gallium/auxiliary/util/u_stream_stdc.c
@@ -32,7 +32,7 @@
#include "pipe/p_config.h"
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
#include <stdio.h>
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index 5b8dd1abb9..1ba82bb21f 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -1155,27 +1155,6 @@ ycbcr_get_tile_rgba(const ushort *src,
}
-static void
-fake_get_tile_rgba(const ushort *src,
- unsigned w, unsigned h,
- float *p,
- unsigned dst_stride)
-{
- unsigned i, j;
-
- for (i = 0; i < h; i++) {
- float *pRow = p;
- for (j = 0; j < w; j++, pRow += 4) {
- pRow[0] =
- pRow[1] =
- pRow[2] =
- pRow[3] = (i ^ j) & 1 ? 1.0f : 0.0f;
- }
- p += dst_stride;
- }
-}
-
-
void
pipe_tile_raw_to_rgba(enum pipe_format format,
void *src,
@@ -1258,8 +1237,10 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
ycbcr_get_tile_rgba((ushort *) src, w, h, dst, dst_stride, TRUE);
break;
default:
- debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
- fake_get_tile_rgba(src, w, h, dst, dst_stride);
+ util_format_read_4f(format,
+ dst, dst_stride * sizeof(float),
+ src, util_format_get_stride(format, w),
+ 0, 0, w, h);
}
}
diff --git a/src/gallium/auxiliary/vl/Makefile b/src/gallium/auxiliary/vl/Makefile
deleted file mode 100644
index 4314c1e8d6..0000000000
--- a/src/gallium/auxiliary/vl/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = vl
-
-C_SOURCES = \
- vl_bitstream_parser.c \
- vl_mpeg12_mc_renderer.c \
- vl_compositor.c \
- vl_csc.c \
- vl_shader_build.c
-
-include ../../Makefile.template
diff --git a/src/gallium/auxiliary/vl/SConscript b/src/gallium/auxiliary/vl/SConscript
deleted file mode 100644
index aed69f5efe..0000000000
--- a/src/gallium/auxiliary/vl/SConscript
+++ /dev/null
@@ -1,13 +0,0 @@
-Import('*')
-
-vl = env.ConvenienceLibrary(
- target = 'vl',
- source = [
- 'vl_bitstream_parser.c',
- 'vl_mpeg12_mc_renderer.c',
- 'vl_compositor.c',
- 'vl_csc.c',
- 'vl_shader_build.c',
- ])
-
-auxiliaries.insert(0, vl)
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index 2299ed2071..5a5d391e94 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -334,11 +334,13 @@ create_frame_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
free(tokens);
}
+#if 0
static void
create_field_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
{
assert(false);
}
+#endif
static void
create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
@@ -442,11 +444,13 @@ create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
free(tokens);
}
+#if 0
static void
create_field_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
{
assert(false);
}
+#endif
static void
create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
@@ -532,11 +536,13 @@ create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
free(tokens);
}
+#if 0
static void
create_field_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
{
assert(false);
}
+#endif
static void
create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
@@ -658,11 +664,13 @@ create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
free(tokens);
}
+#if 0
static void
create_field_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
{
assert(false);
}
+#endif
static void
xfer_buffers_map(struct vl_mpeg12_mc_renderer *r)
@@ -1081,6 +1089,9 @@ gen_macroblock_verts(struct vl_mpeg12_mc_renderer *r,
assert(ycbcr_vb);
assert(pos < r->macroblocks_per_batch);
+ mo_vec[1].x = 0;
+ mo_vec[1].y = 0;
+
switch (mb->mb_type) {
case PIPE_MPEG12_MACROBLOCK_TYPE_BI:
{