From c42e6254cffb8ef480868e9c1942f73129fc4f80 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 31 Jan 2008 13:14:35 +0900 Subject: gallium: Add SCons as alternative build system for Gallium. --- SConstruct | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 SConstruct (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000000..db6161ed51 --- /dev/null +++ b/SConstruct @@ -0,0 +1,214 @@ +####################################################################### +# Top-level SConstruct + +import os +import sys + + +####################################################################### +# Configuration options +# +# For example, invoke scons as +# +# scons debug=1 dri=0 x86=1 +# +# to set configuration variables. Or you can write those options to a file +# named config.py: +# +# # config.py +# debug=1 +# dri=0 +# x86=1 +# +# Invoke +# +# scons -h +# +# to get the full list of options. See scons manpage for more info. +# + +# TODO: auto-detect defaults +opts = Options('config.py') +opts.Add(BoolOption('debug', 'build debug version', False)) +opts.Add(BoolOption('dri', 'build dri drivers', False)) +opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86', + allowed_values=('generic', 'x86', 'x86-64'))) + +env = Environment(options = opts) +Help(opts.GenerateHelpText(env)) + +# for debugging +#print env.Dump() + +if 1: + # platform will be typically 'posix' or 'win32' + platform = env['PLATFORM'] +else: + # platform will be one of 'linux', 'freebsd', 'win32', 'darwin', etc. + platform = sys.platform + if platform == 'linux2': + platform = 'linux' + +# replicate options values in local variables +debug = env['debug'] +dri = env['dri'] +machine = env['machine'] + +# derived options +x86 = machine == 'x86' +gcc = platform == 'posix' +msvc = platform == 'win32' + +Export([ + 'debug', + 'x86', + 'dri', + 'platform', + 'gcc', + 'msvc', +]) + + +####################################################################### +# Environment setup +# +# TODO: put the compiler specific settings in seperate files +# TODO: auto-detect as much as possible + + +# Optimization flags +if gcc: + if debug: + env.Append(CFLAGS = '-O0 -g3') + env.Append(CXXFLAGS = '-O0 -g3') + else: + env.Append(CFLAGS = '-O3 -g3') + env.Append(CXXFLAGS = '-O3 -g3') + + env.Append(CFLAGS = '-Wall -Wmissing-prototypes -std=c99 -ffast-math -pedantic') + env.Append(CXXFLAGS = '-Wall -pedantic') + + # Be nice to Eclipse + env.Append(CFLAGS = '-fmessage-length=0') + env.Append(CXXFLAGS = '-fmessage-length=0') + +# Defines +env.Append(CPPDEFINES = [ + '_POSIX_SOURCE', + ('_POSIX_C_SOURCE', '199309L'), + '_SVID_SOURCE', + '_BSD_SOURCE', + '_GNU_SOURCE', + + 'PTHREADS', + 'HAVE_ALIAS', + 'HAVE_POSIX_MEMALIGN', +]) + +if debug: + env.Append(CPPDEFINES = ['DEBUG']) +else: + env.Append(CPPDEFINES = ['NDEBUG']) + + +# Includes +env.Append(CPPPATH = [ + '#/include', + '#/src/mesa', + '#/src/mesa/main', + '#/src/mesa/pipe', + + '/usr/X11R6/include', +]) + + +# x86 assembly +if x86: + env.Append(CPPDEFINES = [ + 'USE_X86_ASM', + 'USE_MMX_ASM', + 'USE_3DNOW_ASM', + 'USE_SSE_ASM', + ]) + if gcc: + env.Append(CFLAGS = '-m32') + env.Append(CXXFLAGS = '-m32') + +env.Append(LIBPATH = ['/usr/X11R6/lib']) + +env.Append(LIBS = [ + 'm', + 'pthread', + 'expat', + 'dl', +]) + +# DRI +if dri: + env.ParseConfig('pkg-config --cflags --libs libdrm') + env.Append(CPPDEFINES = [ + ('USE_EXTERNAL_DXTN_LIB', '1'), + 'IN_DRI_DRIVER', + 'GLX_DIRECT_RENDERING', + 'GLX_INDIRECT_RENDERING', + ]) + +# libGL +if 1: + env.Append(LIBS = [ + 'X11', + 'Xext', + 'Xxf86vm', + 'Xdamage', + 'Xfixes', + ]) + +Export('env') + + +####################################################################### +# Convenience Library Builder +# based on the stock StaticLibrary and SharedLibrary builders + +def createConvenienceLibBuilder(env): + """This is a utility function that creates the ConvenienceLibrary + Builder in an Environment if it is not there already. + + If it is already there, we return the existing one. + """ + + try: + convenience_lib = env['BUILDERS']['ConvenienceLibrary'] + except KeyError: + action_list = [ Action("$ARCOM", "$ARCOMSTR") ] + if env.Detect('ranlib'): + ranlib_action = Action("$RANLIBCOM", "$RANLIBCOMSTR") + action_list.append(ranlib_action) + + convenience_lib = Builder(action = action_list, + emitter = '$LIBEMITTER', + prefix = '$LIBPREFIX', + suffix = '$LIBSUFFIX', + src_suffix = '$SHOBJSUFFIX', + src_builder = 'SharedObject') + env['BUILDERS']['ConvenienceLibrary'] = convenience_lib + env['BUILDERS']['Library'] = convenience_lib + + return convenience_lib + +createConvenienceLibBuilder(env) + + +####################################################################### +# Invoke SConscripts + +# Put build output in a separate dir +# TODO: make build_dir depend on platform and build type (check +# http://www.scons.org/wiki/AdvancedBuildExample for an example) +build_dir = 'build' + +SConscript( + 'src/mesa/SConscript', + build_dir = build_dir, + duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html +) -- cgit v1.2.3 From f4192cb4ca01c51dd2b8eaa6e17c1acbb4232e0c Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 31 Jan 2008 14:21:49 +0900 Subject: gallium: Make the build output dir depend on the configuration. The build output dirs mimics the old config names: build/linux build/linux-dri build/linux-dri-x86 build/linux-dri-x86-debug ... --- SConstruct | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index db6161ed51..01732b0c52 100644 --- a/SConstruct +++ b/SConstruct @@ -2,6 +2,7 @@ # Top-level SConstruct import os +import os.path import sys @@ -40,7 +41,7 @@ Help(opts.GenerateHelpText(env)) # for debugging #print env.Dump() -if 1: +if 0: # platform will be typically 'posix' or 'win32' platform = env['PLATFORM'] else: @@ -56,7 +57,7 @@ machine = env['machine'] # derived options x86 = machine == 'x86' -gcc = platform == 'posix' +gcc = platform in ('posix', 'linux', 'freebsd', 'darwin') msvc = platform == 'win32' Export([ @@ -202,10 +203,20 @@ createConvenienceLibBuilder(env) ####################################################################### # Invoke SConscripts -# Put build output in a separate dir -# TODO: make build_dir depend on platform and build type (check -# http://www.scons.org/wiki/AdvancedBuildExample for an example) -build_dir = 'build' +# Put build output in a separate dir, which depends on the current configuration +# See also http://www.scons.org/wiki/AdvancedBuildExample +build_topdir = 'build' +build_subdir = platform +if dri: + build_subdir += "-dri" +if x86: + build_subdir += "-x86" +if debug: + build_subdir += "-debug" +build_dir = os.path.join(build_topdir, build_subdir) + +# TODO: Build several variants at the same time? +# http://www.scons.org/wiki/SimultaneousVariantBuilds SConscript( 'src/mesa/SConscript', -- cgit v1.2.3 From 81b6a801f79f3caddf4257a014a6aa80029c8d62 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 6 Feb 2008 14:36:50 +0900 Subject: gallium: Update scons instructions. Propagate user environment. --- SConstruct | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 01732b0c52..47f9b5389b 100644 --- a/SConstruct +++ b/SConstruct @@ -11,7 +11,7 @@ import sys # # For example, invoke scons as # -# scons debug=1 dri=0 x86=1 +# scons debug=1 dri=0 machine=x86 # # to set configuration variables. Or you can write those options to a file # named config.py: @@ -19,7 +19,7 @@ import sys # # config.py # debug=1 # dri=0 -# x86=1 +# machine='x86' # # Invoke # @@ -35,7 +35,9 @@ opts.Add(BoolOption('dri', 'build dri drivers', False)) opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86', allowed_values=('generic', 'x86', 'x86-64'))) -env = Environment(options = opts) +env = Environment( + options = opts, + ENV = os.environ) Help(opts.GenerateHelpText(env)) # for debugging -- cgit v1.2.3 From 0013796948642b281ec84628d6f945b686cd6849 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 7 Feb 2008 19:59:17 +0900 Subject: gallium: Conditionally use posix libraries/includes. --- .gitignore | 1 + SConstruct | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 21 deletions(-) (limited to 'SConstruct') diff --git a/.gitignore b/.gitignore index bf50291fc1..b5e59dfc3e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ lib lib64 .sconsign* config.py +build diff --git a/SConstruct b/SConstruct index 47f9b5389b..22a4072c93 100644 --- a/SConstruct +++ b/SConstruct @@ -95,19 +95,8 @@ if gcc: env.Append(CFLAGS = '-fmessage-length=0') env.Append(CXXFLAGS = '-fmessage-length=0') -# Defines -env.Append(CPPDEFINES = [ - '_POSIX_SOURCE', - ('_POSIX_C_SOURCE', '199309L'), - '_SVID_SOURCE', - '_BSD_SOURCE', - '_GNU_SOURCE', - - 'PTHREADS', - 'HAVE_ALIAS', - 'HAVE_POSIX_MEMALIGN', -]) +# Defines if debug: env.Append(CPPDEFINES = ['DEBUG']) else: @@ -120,8 +109,6 @@ env.Append(CPPPATH = [ '#/src/mesa', '#/src/mesa/main', '#/src/mesa/pipe', - - '/usr/X11R6/include', ]) @@ -137,14 +124,28 @@ if x86: env.Append(CFLAGS = '-m32') env.Append(CXXFLAGS = '-m32') -env.Append(LIBPATH = ['/usr/X11R6/lib']) -env.Append(LIBS = [ - 'm', - 'pthread', - 'expat', - 'dl', -]) +# Posix +if platform in ('posix', 'linux', 'freebsd', 'darwin'): + env.Append(CPPDEFINES = [ + '_POSIX_SOURCE', + ('_POSIX_C_SOURCE', '199309L'), + '_SVID_SOURCE', + '_BSD_SOURCE', + '_GNU_SOURCE', + + 'PTHREADS', + 'HAVE_POSIX_MEMALIGN', + ]) + env.Append(CPPPATH = ['/usr/X11R6/include']) + env.Append(LIBPATH = ['/usr/X11R6/lib']) + env.Append(LIBS = [ + 'm', + 'pthread', + 'expat', + 'dl', + ]) + # DRI if dri: -- cgit v1.2.3 From 33ceb6716a2166db75659fa66d85fb4cfb9633c7 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 10:52:44 +0000 Subject: Update scons build for new code layout. --- SConstruct | 7 +- src/SConscript | 7 ++ src/gallium/SConscript | 23 +++- src/gallium/auxiliary/cso_cache/SConscript | 10 ++ src/gallium/auxiliary/draw/SConscript | 31 +++++ src/gallium/auxiliary/pipebuffer/SConscript | 14 +++ src/gallium/auxiliary/tgsi/SConscript | 14 +++ src/gallium/auxiliary/util/SConscript | 11 ++ src/gallium/drivers/failover/SConscript | 13 +++ src/gallium/winsys/SConscript | 10 ++ src/gallium/winsys/dri/SConscript | 51 +++++++++ src/gallium/winsys/dri/intel/SConscript | 14 +-- src/gallium/winsys/xlib/SConscript | 28 +++++ src/mesa/SConscript | 170 ++-------------------------- src/mesa/drivers/dri/SConscript | 48 -------- 15 files changed, 229 insertions(+), 222 deletions(-) create mode 100644 src/SConscript create mode 100644 src/gallium/auxiliary/cso_cache/SConscript create mode 100644 src/gallium/auxiliary/draw/SConscript create mode 100644 src/gallium/auxiliary/pipebuffer/SConscript create mode 100644 src/gallium/auxiliary/tgsi/SConscript create mode 100644 src/gallium/auxiliary/util/SConscript create mode 100644 src/gallium/drivers/failover/SConscript create mode 100644 src/gallium/winsys/SConscript create mode 100644 src/gallium/winsys/dri/SConscript create mode 100644 src/gallium/winsys/xlib/SConscript delete mode 100644 src/mesa/drivers/dri/SConscript (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 22a4072c93..1126aff21b 100644 --- a/SConstruct +++ b/SConstruct @@ -108,7 +108,10 @@ env.Append(CPPPATH = [ '#/include', '#/src/mesa', '#/src/mesa/main', - '#/src/mesa/pipe', + '#/src/gallium/include/pipe', + '#/src/gallium/include', + '#/src/gallium/auxiliary', + '#/src/gallium/drivers', ]) @@ -222,7 +225,7 @@ build_dir = os.path.join(build_topdir, build_subdir) # http://www.scons.org/wiki/SimultaneousVariantBuilds SConscript( - 'src/mesa/SConscript', + 'src/SConscript', build_dir = build_dir, duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html ) diff --git a/src/SConscript b/src/SConscript new file mode 100644 index 0000000000..5b09943894 --- /dev/null +++ b/src/SConscript @@ -0,0 +1,7 @@ +Import('*') + +SConscript([ + 'gallium/SConscript', + 'mesa/SConscript', + 'gallium/winsys/SConscript', +]) diff --git a/src/gallium/SConscript b/src/gallium/SConscript index d9c20e0100..a835f6d661 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -1,9 +1,24 @@ Import('*') -#env = env.Clone() +env = env.Clone() + +auxiliaries = [] + +Export('auxiliaries') + SConscript([ - 'softpipe/SConscript', - 'i915simple/SConscript', - 'i965simple/SConscript', + # NOTE: order matters! + 'auxiliary/util/SConscript', + 'auxiliary/tgsi/SConscript', + 'auxiliary/cso_cache/SConscript', + 'auxiliary/draw/SConscript', + #'auxiliary/llvm/SConscript', + 'auxiliary/pipebuffer/SConscript', + + 'drivers/softpipe/SConscript', + 'drivers/i915simple/SConscript', + 'drivers/i965simple/SConscript', + 'drivers/failover/SConscript', + #'drivers/cell/SConscript', ]) diff --git a/src/gallium/auxiliary/cso_cache/SConscript b/src/gallium/auxiliary/cso_cache/SConscript new file mode 100644 index 0000000000..9751881613 --- /dev/null +++ b/src/gallium/auxiliary/cso_cache/SConscript @@ -0,0 +1,10 @@ +Import('*') + +cso_cache = env.ConvenienceLibrary( + target = 'cso_cache', + source = [ + 'cso_cache.c', + 'cso_hash.c', + ]) + +auxiliaries.insert(0, cso_cache) diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript new file mode 100644 index 0000000000..8e3a8caa74 --- /dev/null +++ b/src/gallium/auxiliary/draw/SConscript @@ -0,0 +1,31 @@ +Import('*') + +draw = env.ConvenienceLibrary( + target = 'draw', + source = [ + 'draw_clip.c', + 'draw_vs_exec.c', + 'draw_vs_sse.c', + 'draw_vs_llvm.c', + 'draw_context.c', + 'draw_cull.c', + 'draw_debug.c', + 'draw_flatshade.c', + 'draw_offset.c', + 'draw_prim.c', + 'draw_stipple.c', + 'draw_twoside.c', + 'draw_unfilled.c', + 'draw_validate.c', + 'draw_vbuf.c', + 'draw_vertex.c', + 'draw_vertex_cache.c', + 'draw_vertex_fetch.c', + 'draw_vertex_shader.c', + 'draw_vf.c', + 'draw_vf_generic.c', + 'draw_vf_sse.c', + 'draw_wide_prims.c', + ]) + +auxiliaries.insert(0, draw) diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript new file mode 100644 index 0000000000..3d41fd84a6 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -0,0 +1,14 @@ +Import('*') + +pipebuffer = env.ConvenienceLibrary( + target = 'pipebuffer', + source = [ + 'pb_buffer_fenced.c', + 'pb_buffer_malloc.c', + 'pb_bufmgr_fenced.c', + 'pb_bufmgr_mm.c', + 'pb_bufmgr_pool.c', + 'pb_winsys.c', + ]) + +auxiliaries.insert(0, pipebuffer) diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript new file mode 100644 index 0000000000..8464bfe944 --- /dev/null +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -0,0 +1,14 @@ +Import('*') + +tgsi = env.ConvenienceLibrary( + target = 'tgsi', + source = [ + 'exec/tgsi_exec.c', + 'exec/tgsi_sse2.c', + 'util/tgsi_build.c', + 'util/tgsi_dump.c', + 'util/tgsi_parse.c', + 'util/tgsi_util.c', + ]) + +auxiliaries.insert(0, tgsi) diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript new file mode 100644 index 0000000000..b126cf44d6 --- /dev/null +++ b/src/gallium/auxiliary/util/SConscript @@ -0,0 +1,11 @@ +Import('*') + +util = env.ConvenienceLibrary( + target = 'util', + source = [ + 'p_debug.c', + 'p_tile.c', + 'p_util.c', + ]) + +auxiliaries.insert(0, util) diff --git a/src/gallium/drivers/failover/SConscript b/src/gallium/drivers/failover/SConscript new file mode 100644 index 0000000000..f8e9b1b491 --- /dev/null +++ b/src/gallium/drivers/failover/SConscript @@ -0,0 +1,13 @@ +Import('*') + +env = env.Clone() + +failover = env.ConvenienceLibrary( + target = 'failover', + source = [ + 'fo_state.c', + 'fo_state_emit.c', + 'fo_context.c', + ]) + +Export('failover') diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript new file mode 100644 index 0000000000..32215d8d58 --- /dev/null +++ b/src/gallium/winsys/SConscript @@ -0,0 +1,10 @@ +Import('*') + +if dri: + SConscript([ + 'dri/SConscript', + ]) +else: + SConscript([ + 'xlib/SConscript', + ]) diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript new file mode 100644 index 0000000000..8c56ce917c --- /dev/null +++ b/src/gallium/winsys/dri/SConscript @@ -0,0 +1,51 @@ +Import('*') + +drienv = env.Clone() + +drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', +]) + +drienv.ParseConfig('pkg-config --cflags --libs libdrm') + +COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', +] + +COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', +] + +Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', +]) + +# TODO: Installation +#install: $(LIBNAME) +# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) +# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + +SConscript([ + 'intel/SConscript', +]) diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index a7cc10450e..525ba580e8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -9,11 +9,6 @@ env.Append(CPPPATH = [ #MINIGLX_SOURCES = server/intel_dri.c -pipe_drivers = [ - softpipe, - i915simple -] - DRIVER_SOURCES = [ 'intel_winsys_pipe.c', 'intel_winsys_softpipe.c', @@ -31,11 +26,14 @@ sources = \ COMMON_BM_SOURCES + \ DRIVER_SOURCES -# DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ -# && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") +drivers = [ + softpipe, + i915simple +] +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = pipe_drivers + env['LIBS'], + LIBS = mesa + drivers + auxiliaries + env['LIBS'], ) \ No newline at end of file diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript new file mode 100644 index 0000000000..f8aa5ef945 --- /dev/null +++ b/src/gallium/winsys/xlib/SConscript @@ -0,0 +1,28 @@ +####################################################################### +# SConscript for xlib winsys + +Import('*') + + +sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', +] + +drivers = [ + softpipe, + i915simple, + i965simple, +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], +) diff --git a/src/mesa/SConscript b/src/mesa/SConscript index faf8c84872..a828133580 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -1,7 +1,5 @@ ####################################################################### -# SConscript for mesa -# -# TODO: Split this into per-module SConscripts +# SConscript for Mesa Import('*') @@ -116,53 +114,6 @@ VF_SOURCES = [ 'vf/vf_sse.c', ] -DRAW_SOURCES = [ - 'pipe/draw/draw_clip.c', - 'pipe/draw/draw_context.c', - 'pipe/draw/draw_cull.c', - 'pipe/draw/draw_debug.c', - 'pipe/draw/draw_flatshade.c', - 'pipe/draw/draw_offset.c', - 'pipe/draw/draw_prim.c', - 'pipe/draw/draw_stipple.c', - 'pipe/draw/draw_twoside.c', - 'pipe/draw/draw_unfilled.c', - 'pipe/draw/draw_validate.c', - 'pipe/draw/draw_vbuf.c', - 'pipe/draw/draw_vertex.c', - 'pipe/draw/draw_vertex_cache.c', - 'pipe/draw/draw_vertex_fetch.c', - 'pipe/draw/draw_vertex_shader.c', - 'pipe/draw/draw_vertex_shader_llvm.c', - 'pipe/draw/draw_vf.c', - 'pipe/draw/draw_vf_generic.c', - 'pipe/draw/draw_vf_sse.c', - 'pipe/draw/draw_wide_prims.c', -] - -TGSIEXEC_SOURCES = [ - 'pipe/tgsi/exec/tgsi_exec.c', - 'pipe/tgsi/exec/tgsi_sse2.c', -] - -TGSIUTIL_SOURCES = [ - 'pipe/tgsi/util/tgsi_build.c', - 'pipe/tgsi/util/tgsi_dump.c', - 'pipe/tgsi/util/tgsi_parse.c', - 'pipe/tgsi/util/tgsi_util.c', -] - -STATECACHE_SOURCES = [ - 'pipe/cso_cache/cso_hash.c', - 'pipe/cso_cache/cso_cache.c', -] - -PIPEUTIL_SOURCES = [ - 'pipe/util/p_debug.c', - 'pipe/util/p_tile.c', - 'pipe/util/p_util.c', -] - STATETRACKER_SOURCES = [ 'state_tracker/st_atom.c', 'state_tracker/st_atom_blend.c', @@ -311,126 +262,25 @@ else: ASM_SOURCES = [] API_SOURCES = [] - -####################################################################### -# Driver sources - - -X11_DRIVER_SOURCES = [ - 'pipe/xlib/glxapi.c', - 'pipe/xlib/fakeglx.c', - 'pipe/xlib/xfonts.c', - 'pipe/xlib/xm_api.c', - 'pipe/xlib/xm_winsys.c', - 'pipe/xlib/xm_winsys_aub.c', - 'pipe/xlib/brw_aub.c', -] - -OSMESA_DRIVER_SOURCES = [ - 'drivers/osmesa/osmesa.c', -] - -GLIDE_DRIVER_SOURCES = [ - 'drivers/glide/fxapi.c', - 'drivers/glide/fxdd.c', - 'drivers/glide/fxddspan.c', - 'drivers/glide/fxddtex.c', - 'drivers/glide/fxsetup.c', - 'drivers/glide/fxtexman.c', - 'drivers/glide/fxtris.c', - 'drivers/glide/fxvb.c', - 'drivers/glide/fxglidew.c', - 'drivers/glide/fxg.c', -] - -SVGA_DRIVER_SOURCES = [ - 'drivers/svga/svgamesa.c', - 'drivers/svga/svgamesa8.c', - 'drivers/svga/svgamesa15.c', - 'drivers/svga/svgamesa16.c', - 'drivers/svga/svgamesa24.c', - 'drivers/svga/svgamesa32.c', -] - -FBDEV_DRIVER_SOURCES = [ - 'drivers/fbdev/glfbdev.c', -] - - -### All the core C sources - SOLO_SOURCES = \ MAIN_SOURCES + \ MATH_SOURCES + \ VBO_SOURCES + \ VF_SOURCES + \ - DRAW_SOURCES + \ - TGSIEXEC_SOURCES + \ - TGSIUTIL_SOURCES + \ - PIPEUTIL_SOURCES + \ - STATECACHE_SOURCES + \ STATETRACKER_SOURCES + \ SHADER_SOURCES + \ ASM_SOURCES + \ SLANG_SOURCES -CORE_SOURCES = \ - GLAPI_SOURCES + API_SOURCES + \ - SOLO_SOURCES - -ALL_SOURCES = \ - GLAPI_SOURCES + API_SOURCES + \ - SOLO_SOURCES + \ - ASM_SOURCES + \ - X11_DRIVER_SOURCES + \ - FBDEV_DRIVER_SOURCES + \ - OSMESA_DRIVER_SOURCES - - -###################################################################### -# Gallium sources - -SConscript([ - 'pipe/SConscript', -]) - - -###################################################################### -# libGL +mesa = env.ConvenienceLibrary( + target = 'mesa', + source = SOLO_SOURCES, +) +Export('mesa') if not dri: - STAND_ALONE_DRIVER_SOURCES = \ - CORE_SOURCES + \ - X11_DRIVER_SOURCES - - Import( - 'softpipe', - 'i915simple', - 'i965simple' + glapi = env.ConvenienceLibrary( + target = 'glapi', + source = GLAPI_SOURCES + API_SOURCES, ) - - pipe_drivers = [ - softpipe, - i965simple - ] - - env.SharedLibrary( - target ='GL', - source = STAND_ALONE_DRIVER_SOURCES, - LIBS = [softpipe, i965simple] + env['LIBS'], - ) - - -###################################################################### -# Driver sources - -if dri: - mesa = env.ConvenienceLibrary( - target = 'mesa', - source = SOLO_SOURCES, - ) - env.Prepend(LIBS = [mesa]) - - SConscript([ - 'drivers/dri/SConscript', - ]) + Export('glapi') diff --git a/src/mesa/drivers/dri/SConscript b/src/mesa/drivers/dri/SConscript deleted file mode 100644 index d32bd08669..0000000000 --- a/src/mesa/drivers/dri/SConscript +++ /dev/null @@ -1,48 +0,0 @@ -Import('*') - -drienv = env.Clone() - -drienv.Replace(CPPPATH = [ - '#src/mesa/drivers/dri/common', - '#include', - '#include/GL/internal', - '#src/mesa', - '#src/mesa/main', - '#src/mesa/glapi', - '#src/mesa/math', - '#src/mesa/transform', - '#src/mesa/shader', - '#src/mesa/swrast', - '#src/mesa/swrast_setup', - '#src/egl/main', - '#src/egl/drivers/dri', -]) - -drienv.ParseConfig('pkg-config --cflags --libs libdrm') - -COMMON_GALLIUM_SOURCES = [ - '../common/utils.c', - '../common/vblank.c', - '../common/dri_util.c', - '../common/xmlconfig.c', -] - -COMMON_BM_SOURCES = [ - '../common/dri_bufmgr.c', - '../common/dri_drmpool.c', -] - -Export([ - 'drienv', - 'COMMON_GALLIUM_SOURCES', - 'COMMON_BM_SOURCES', -]) - -# TODO: Installation -#install: $(LIBNAME) -# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) -# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - -SConscript([ - 'intel_winsys/SConscript', -]) -- cgit v1.2.3 From 687a8b96ef13658bbe779d0011ce1144844f1972 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 18 Feb 2008 20:02:42 +0900 Subject: Standardize on using the pipe/ include prefix. --- SConstruct | 1 - src/gallium/Makefile.template | 1 - src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 10 +++++----- src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c | 4 ++-- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 8 ++++---- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 10 +++++----- src/gallium/drivers/i915simple/i915_state_immediate.c | 2 +- src/gallium/drivers/i915simple/i915_state_inlines.h | 4 ++-- src/gallium/drivers/softpipe/sp_state_surface.c | 2 +- 9 files changed, 20 insertions(+), 22 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 1126aff21b..4fb51f2e6d 100644 --- a/SConstruct +++ b/SConstruct @@ -108,7 +108,6 @@ env.Append(CPPPATH = [ '#/include', '#/src/mesa', '#/src/mesa/main', - '#/src/gallium/include/pipe', '#/src/gallium/include', '#/src/gallium/auxiliary', '#/src/gallium/drivers', diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 6ad58c205c..6698212e77 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -16,7 +16,6 @@ OBJECTS = $(C_SOURCES:.c=.o) \ INCLUDES = \ -I. \ -I$(TOP)/src/gallium/include \ - -I$(TOP)/src/gallium/include/pipe \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/mesa \ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index f4fc3f6d71..bc85c4b19f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -36,11 +36,11 @@ #include "linked_list.h" -#include "p_compiler.h" -#include "p_debug.h" -#include "p_winsys.h" -#include "p_thread.h" -#include "p_util.h" +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_winsys.h" +#include "pipe/p_thread.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index c535d3276c..bffca5b244 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -34,8 +34,8 @@ */ -#include "p_debug.h" -#include "p_util.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 8b1b51c0e2..969aab51b5 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -36,10 +36,10 @@ #include "linked_list.h" -#include "p_defines.h" -#include "p_debug.h" -#include "p_thread.h" -#include "p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 04477a865a..beb145b7cb 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -37,11 +37,11 @@ #include "linked_list.h" -#include "p_compiler.h" -#include "p_debug.h" -#include "p_thread.h" -#include "p_defines.h" -#include "p_util.h" +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_thread.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c index 07031fc6c5..dfbbcab624 100644 --- a/src/gallium/drivers/i915simple/i915_state_immediate.c +++ b/src/gallium/drivers/i915simple/i915_state_immediate.c @@ -33,7 +33,7 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_reg.h" -#include "p_util.h" +#include "pipe/p_util.h" /* All state expressable with the LOAD_STATE_IMMEDIATE_1 packet. diff --git a/src/gallium/drivers/i915simple/i915_state_inlines.h b/src/gallium/drivers/i915simple/i915_state_inlines.h index 0934ac79a4..378de8f9c4 100644 --- a/src/gallium/drivers/i915simple/i915_state_inlines.h +++ b/src/gallium/drivers/i915simple/i915_state_inlines.h @@ -28,8 +28,8 @@ #ifndef I915_STATE_INLINES_H #define I915_STATE_INLINES_H -#include "p_compiler.h" -#include "p_defines.h" +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" #include "i915_reg.h" diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c index e2c6893e9f..124b18b708 100644 --- a/src/gallium/drivers/softpipe/sp_state_surface.c +++ b/src/gallium/drivers/softpipe/sp_state_surface.c @@ -27,7 +27,7 @@ /* Authors: Keith Whitwell */ -#include "p_inlines.h" +#include "pipe/p_inlines.h" #include "sp_context.h" #include "sp_state.h" -- cgit v1.2.3 From e773a813cf475e2a7ad79ea1ec698bf2530d0433 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 10:50:39 +0900 Subject: Initial scons support to build gallivm. Not yet complete. --- SConstruct | 13 +++++++++++++ src/gallium/SConscript | 6 +++++- src/gallium/auxiliary/gallivm/SConscript | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/gallium/auxiliary/gallivm/SConscript (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 4fb51f2e6d..b20f88a303 100644 --- a/SConstruct +++ b/SConstruct @@ -32,6 +32,7 @@ import sys opts = Options('config.py') opts.Add(BoolOption('debug', 'build debug version', False)) opts.Add(BoolOption('dri', 'build dri drivers', False)) +opts.Add(BoolOption('llvm', 'use llvm', False)) opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86', allowed_values=('generic', 'x86', 'x86-64'))) @@ -55,6 +56,7 @@ else: # replicate options values in local variables debug = env['debug'] dri = env['dri'] +llvm = env['llvm'] machine = env['machine'] # derived options @@ -66,6 +68,7 @@ Export([ 'debug', 'x86', 'dri', + 'llvm', 'platform', 'gcc', 'msvc', @@ -159,6 +162,14 @@ if dri: 'GLX_INDIRECT_RENDERING', ]) +# LLVM +if llvm: + # See also http://www.scons.org/wiki/UsingPkgConfig + env.ParseConfig('llvm-config --cflags --ldflags --libs') + env.Append(CPPDEFINES = ['MESA_LLVM']) + env.Append(CXXFLAGS = ['-Wno-long-long']) + + # libGL if 1: env.Append(LIBS = [ @@ -214,6 +225,8 @@ build_topdir = 'build' build_subdir = platform if dri: build_subdir += "-dri" +if llvm: + build_subdir += "-llvm" if x86: build_subdir += "-x86" if debug: diff --git a/src/gallium/SConscript b/src/gallium/SConscript index ea55ed2ed5..c505eee792 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -13,9 +13,13 @@ SConscript([ 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', 'auxiliary/draw/SConscript', - #'auxiliary/gallivm/SConscript', 'auxiliary/pipebuffer/SConscript', +]) + +if llvm: + SConscript(['auxiliary/gallivm/SConscript']) +SConscript([ 'drivers/softpipe/SConscript', 'drivers/i915simple/SConscript', 'drivers/i965simple/SConscript', diff --git a/src/gallium/auxiliary/gallivm/SConscript b/src/gallium/auxiliary/gallivm/SConscript new file mode 100644 index 0000000000..c0aa51b90a --- /dev/null +++ b/src/gallium/auxiliary/gallivm/SConscript @@ -0,0 +1,16 @@ +Import('*') + +gallivm = env.ConvenienceLibrary( + target = 'gallivm', + source = [ + 'gallivm.cpp', + 'gallivm_cpu.cpp', + 'instructions.cpp', + 'loweringpass.cpp', + 'tgsitollvm.cpp', + 'storage.cpp', + 'storagesoa.cpp', + 'instructionssoa.cpp', + ]) + +auxiliaries.insert(0, gallivm) -- cgit v1.2.3 From b9da3791c934e05b82063a8c79c423a0a8e29a94 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 15:07:53 +0900 Subject: Remove src/mesa and src/mesa/main from gallium source include paths. --- SConstruct | 2 - src/gallium/Makefile.template | 2 - src/gallium/auxiliary/draw/draw_vf_sse.c | 3 +- src/gallium/auxiliary/pipebuffer/linked_list.h | 91 ------ .../auxiliary/pipebuffer/pb_buffer_fenced.c | 3 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 3 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 3 +- src/gallium/auxiliary/util/u_double_list.h | 91 ++++++ src/gallium/auxiliary/util/u_simple_list.h | 197 +++++++++++++ src/gallium/drivers/i915simple/i915_debug.c | 2 - src/gallium/include/pipe/p_thread.h | 327 +++++++++++++++++++-- src/gallium/winsys/dri/intel/SConscript | 2 +- src/gallium/winsys/dri/intel/intel_batchpool.c | 15 +- src/gallium/winsys/xlib/SConscript | 6 + src/gallium/winsys/xlib/brw_aub.c | 16 +- src/mesa/SConscript | 7 + src/mesa/x86/common_x86_asm.S | 2 +- 17 files changed, 620 insertions(+), 152 deletions(-) delete mode 100644 src/gallium/auxiliary/pipebuffer/linked_list.h create mode 100644 src/gallium/auxiliary/util/u_double_list.h create mode 100644 src/gallium/auxiliary/util/u_simple_list.h (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index b20f88a303..6cb07302e8 100644 --- a/SConstruct +++ b/SConstruct @@ -109,8 +109,6 @@ else: # Includes env.Append(CPPPATH = [ '#/include', - '#/src/mesa', - '#/src/mesa/main', '#/src/gallium/include', '#/src/gallium/auxiliary', '#/src/gallium/drivers', diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 6698212e77..4e462b5c97 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -18,8 +18,6 @@ INCLUDES = \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/mesa/main \ -I$(TOP)/include \ $(DRIVER_INCLUDES) diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c index 6076f9849d..aff4ffd985 100644 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ b/src/gallium/auxiliary/draw/draw_vf_sse.c @@ -26,9 +26,8 @@ */ -#include "simple_list.h" - #include "pipe/p_compiler.h" +#include "util/u_simple_list.h" #include "draw_vf.h" diff --git a/src/gallium/auxiliary/pipebuffer/linked_list.h b/src/gallium/auxiliary/pipebuffer/linked_list.h deleted file mode 100644 index e99817fb13..0000000000 --- a/src/gallium/auxiliary/pipebuffer/linked_list.h +++ /dev/null @@ -1,91 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - **************************************************************************/ - -/** - * \file - * List macros heavily inspired by the Linux kernel - * list handling. No list looping yet. - * - * Is not threadsafe, so common operations need to - * be protected using an external mutex. - */ - -#ifndef LINKED_LIST_H_ -#define LINKED_LIST_H_ - - -#include - - -struct list_head -{ - struct list_head *prev; - struct list_head *next; -}; - - -#define LIST_INITHEAD(__item) \ - do { \ - (__item)->prev = (__item); \ - (__item)->next = (__item); \ - } while (0) - -#define LIST_ADD(__item, __list) \ - do { \ - (__item)->prev = (__list); \ - (__item)->next = (__list)->next; \ - (__list)->next->prev = (__item); \ - (__list)->next = (__item); \ - } while (0) - -#define LIST_ADDTAIL(__item, __list) \ - do { \ - (__item)->next = (__list); \ - (__item)->prev = (__list)->prev; \ - (__list)->prev->next = (__item); \ - (__list)->prev = (__item); \ - } while(0) - -#define LIST_DEL(__item) \ - do { \ - (__item)->prev->next = (__item)->next; \ - (__item)->next->prev = (__item)->prev; \ - } while(0) - -#define LIST_DELINIT(__item) \ - do { \ - (__item)->prev->next = (__item)->next; \ - (__item)->next->prev = (__item)->prev; \ - (__item)->next = (__item); \ - (__item)->prev = (__item); \ - } while(0) - -#define LIST_ENTRY(__type, __item, __field) \ - ((__type *)(((char *)(__item)) - offsetof(__type, __field))) - - -#endif /*LINKED_LIST_H_*/ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index bc85c4b19f..e2ee72ed1f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -34,13 +34,12 @@ */ -#include "linked_list.h" - #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_winsys.h" #include "pipe/p_thread.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "pb_buffer.h" #include "pb_buffer_fenced.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 983a105347..ff4fd123f3 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -33,12 +33,11 @@ */ -#include "linked_list.h" - #include "pipe/p_defines.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "util/u_mm.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index beb145b7cb..528e9528f6 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -35,13 +35,12 @@ */ -#include "linked_list.h" - #include "pipe/p_compiler.h" #include "pipe/p_debug.h" #include "pipe/p_thread.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "util/u_double_list.h" #include "pb_buffer.h" #include "pb_bufmgr.h" diff --git a/src/gallium/auxiliary/util/u_double_list.h b/src/gallium/auxiliary/util/u_double_list.h new file mode 100644 index 0000000000..8cb10c9820 --- /dev/null +++ b/src/gallium/auxiliary/util/u_double_list.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +/** + * \file + * List macros heavily inspired by the Linux kernel + * list handling. No list looping yet. + * + * Is not threadsafe, so common operations need to + * be protected using an external mutex. + */ + +#ifndef _U_DOUBLE_LIST_H_ +#define _U_DOUBLE_LIST_H_ + + +#include + + +struct list_head +{ + struct list_head *prev; + struct list_head *next; +}; + + +#define LIST_INITHEAD(__item) \ + do { \ + (__item)->prev = (__item); \ + (__item)->next = (__item); \ + } while (0) + +#define LIST_ADD(__item, __list) \ + do { \ + (__item)->prev = (__list); \ + (__item)->next = (__list)->next; \ + (__list)->next->prev = (__item); \ + (__list)->next = (__item); \ + } while (0) + +#define LIST_ADDTAIL(__item, __list) \ + do { \ + (__item)->next = (__list); \ + (__item)->prev = (__list)->prev; \ + (__list)->prev->next = (__item); \ + (__list)->prev = (__item); \ + } while(0) + +#define LIST_DEL(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + } while(0) + +#define LIST_DELINIT(__item) \ + do { \ + (__item)->prev->next = (__item)->next; \ + (__item)->next->prev = (__item)->prev; \ + (__item)->next = (__item); \ + (__item)->prev = (__item); \ + } while(0) + +#define LIST_ENTRY(__type, __item, __field) \ + ((__type *)(((char *)(__item)) - offsetof(__type, __field))) + + +#endif /*_U_DOUBLE_LIST_H_*/ diff --git a/src/gallium/auxiliary/util/u_simple_list.h b/src/gallium/auxiliary/util/u_simple_list.h new file mode 100644 index 0000000000..f5f43b0faa --- /dev/null +++ b/src/gallium/auxiliary/util/u_simple_list.h @@ -0,0 +1,197 @@ +/** + * \file simple_list.h + * Simple macros for type-safe, intrusive lists. + * + * Intended to work with a list sentinal which is created as an empty + * list. Insert & delete are O(1). + * + * \author + * (C) 1997, Keith Whitwell + */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _U_SIMPLE_LIST_H_ +#define _U_SIMPLE_LIST_H_ + +/** + * Remove an element from list. + * + * \param elem element to remove. + */ +#define remove_from_list(elem) \ +do { \ + (elem)->next->prev = (elem)->prev; \ + (elem)->prev->next = (elem)->next; \ +} while (0) + +/** + * Insert an element to the list head. + * + * \param list list. + * \param elem element to insert. + */ +#define insert_at_head(list, elem) \ +do { \ + (elem)->prev = list; \ + (elem)->next = (list)->next; \ + (list)->next->prev = elem; \ + (list)->next = elem; \ +} while(0) + +/** + * Insert an element to the list tail. + * + * \param list list. + * \param elem element to insert. + */ +#define insert_at_tail(list, elem) \ +do { \ + (elem)->next = list; \ + (elem)->prev = (list)->prev; \ + (list)->prev->next = elem; \ + (list)->prev = elem; \ +} while(0) + +/** + * Move an element to the list head. + * + * \param list list. + * \param elem element to move. + */ +#define move_to_head(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_head(list, elem); \ +} while (0) + +/** + * Move an element to the list tail. + * + * \param list list. + * \param elem element to move. + */ +#define move_to_tail(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_tail(list, elem); \ +} while (0) + +/** + * Make a empty list empty. + * + * \param sentinal list (sentinal element). + */ +#define make_empty_list(sentinal) \ +do { \ + (sentinal)->next = sentinal; \ + (sentinal)->prev = sentinal; \ +} while (0) + +/** + * Get list first element. + * + * \param list list. + * + * \return pointer to first element. + */ +#define first_elem(list) ((list)->next) + +/** + * Get list last element. + * + * \param list list. + * + * \return pointer to last element. + */ +#define last_elem(list) ((list)->prev) + +/** + * Get next element. + * + * \param elem element. + * + * \return pointer to next element. + */ +#define next_elem(elem) ((elem)->next) + +/** + * Get previous element. + * + * \param elem element. + * + * \return pointer to previous element. + */ +#define prev_elem(elem) ((elem)->prev) + +/** + * Test whether element is at end of the list. + * + * \param list list. + * \param elem element. + * + * \return non-zero if element is at end of list, or zero otherwise. + */ +#define at_end(list, elem) ((elem) == (list)) + +/** + * Test if a list is empty. + * + * \param list list. + * + * \return non-zero if list empty, or zero otherwise. + */ +#define is_empty_list(list) ((list)->next == (list)) + +/** + * Walk through the elements of a list. + * + * \param ptr pointer to the current element. + * \param list list. + * + * \note It should be followed by a { } block or a single statement, as in a \c + * for loop. + */ +#define foreach(ptr, list) \ + for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) + +/** + * Walk through the elements of a list. + * + * Same as #foreach but lets you unlink the current value during a list + * traversal. Useful for freeing a list, element by element. + * + * \param ptr pointer to the current element. + * \param t temporary pointer. + * \param list list. + * + * \note It should be followed by a { } block or a single statement, as in a \c + * for loop. + */ +#define foreach_s(ptr, t, list) \ + for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) + +#endif /* _U_SIMPLE_LIST_H_ */ diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c index 94db44e1aa..78102dbac2 100644 --- a/src/gallium/drivers/i915simple/i915_debug.c +++ b/src/gallium/drivers/i915simple/i915_debug.c @@ -25,8 +25,6 @@ * **************************************************************************/ -//#include "imports.h" - #include "i915_reg.h" #include "i915_context.h" #include "i915_winsys.h" diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h index cd432c547c..4325abc951 100644 --- a/src/gallium/include/pipe/p_thread.h +++ b/src/gallium/include/pipe/p_thread.h @@ -1,54 +1,317 @@ /************************************************************************** * + * Copyright 1999-2006 Brian Paul * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ -#ifndef P_THREAD_H -#define P_THREAD_H +/** + * @file + * Thread + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * + * + * + * DOCUMENTATION + * + * This thread module exports the following types: + * _glthread_TSD Thread-specific data area + * _glthread_Thread Thread datatype + * _glthread_Mutex Mutual exclusion lock + * + * Macros: + * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex + * _glthread_INIT_MUTEX(name) Initialize a mutex + * _glthread_LOCK_MUTEX(name) Lock a mutex + * _glthread_UNLOCK_MUTEX(name) Unlock a mutex + * + * Functions: + * _glthread_GetID(v) Get integer thread ID + * _glthread_InitTSD() Initialize thread-specific data + * _glthread_GetTSD() Get thread-specific data + * _glthread_SetTSD() Set thread-specific data + * + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef _P_THREAD_H_ +#define _P_THREAD_H_ + + +#if defined(USE_MGL_NAMESPACE) +#define _glapi_Dispatch _mglapi_Dispatch +#endif + + + +#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ + defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ + && !defined(THREADS) +# define THREADS +#endif + +#ifdef VMS +#include +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(PTHREADS) +#include /* POSIX threads headers */ + +typedef struct { + pthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef pthread_t _glthread_Thread; + +typedef pthread_mutex_t _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + pthread_mutex_init(&(name), NULL) + +#define _glthread_DESTROY_MUTEX(name) \ + pthread_mutex_destroy(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) pthread_mutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) pthread_mutex_unlock(&(name)) + +#endif /* PTHREADS */ + + + + +/* + * Solaris threads. Use only up to Solaris 2.4. + * Solaris 2.5 and higher provide POSIX threads. + * Be sure to compile with -mt on the Solaris compilers, or + * use -D_REENTRANT if using gcc. + */ +#ifdef SOLARIS_THREADS +#include + +typedef struct { + thread_key_t key; + mutex_t keylock; + int initMagic; +} _glthread_TSD; + +typedef thread_t _glthread_Thread; + +typedef mutex_t _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 +#define _glthread_INIT_MUTEX(name) (void) name +#define _glthread_DESTROY_MUTEX(name) (void) name +#define _glthread_LOCK_MUTEX(name) (void) name +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* SOLARIS_THREADS */ + + + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include + +typedef struct { + DWORD key; + int initMagic; +} _glthread_TSD; + +typedef HANDLE _glthread_Thread; + +typedef CRITICAL_SECTION _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) /*static*/ _glthread_Mutex name = {0,0,0,0,0,0} +#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) +#define _glthread_DESTROY_MUTEX(name) DeleteCriticalSection(&name) +#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) +#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) + +#endif /* WIN32_THREADS */ + + -#include "p_compiler.h" /* - * XXX: We should come up with a system-independent thread definitions. - * XXX: Patching glthread defs for now. + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. */ +#ifdef USE_XTHREADS +#include + +typedef struct { + xthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef xthread_t _glthread_Thread; + +typedef xmutex_rec _glthread_Mutex; + +#ifdef XMUTEX_INITIALIZER +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = XMUTEX_INITIALIZER +#else +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name +#endif + +#define _glthread_INIT_MUTEX(name) \ + xmutex_init(&(name)) + +#define _glthread_DESTROY_MUTEX(name) \ + xmutex_clear(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) xmutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) xmutex_unlock(&(name)) + +#endif /* USE_XTHREADS */ + + + +/* + * BeOS threads. R5.x required. + */ +#ifdef BEOS_THREADS + +#include +#include + +typedef struct { + int32 key; + int initMagic; +} _glthread_TSD; + +typedef thread_id _glthread_Thread; + +/* Use Benaphore, aka speeder semaphore */ +typedef struct { + int32 lock; + sem_id sem; +} benaphore; +typedef benaphore _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = { 0, 0 } +#define _glthread_INIT_MUTEX(name) name.sem = create_sem(0, #name"_benaphore"), name.lock = 0 +#define _glthread_DESTROY_MUTEX(name) delete_sem(name.sem), name.lock = 0 +#define _glthread_LOCK_MUTEX(name) if (name.sem == 0) _glthread_INIT_MUTEX(name); \ + if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem) +#define _glthread_UNLOCK_MUTEX(name) if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem) + +#endif /* BEOS_THREADS */ + + + +#ifndef THREADS + +/* + * THREADS not defined + */ + +typedef unsigned _glthread_TSD; + +typedef unsigned _glthread_Thread; + +typedef unsigned _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 + +#define _glthread_INIT_MUTEX(name) (void) name + +#define _glthread_DESTROY_MUTEX(name) (void) name + +#define _glthread_LOCK_MUTEX(name) (void) name + +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* THREADS */ + + + +/* + * Platform independent thread specific data API. + */ + +extern unsigned long +_glthread_GetID(void); + + +extern void +_glthread_InitTSD(_glthread_TSD *); + + +extern void * +_glthread_GetTSD(_glthread_TSD *); -#ifndef __MSC__ -#include "glapi/glthread.h" +extern void +_glthread_SetTSD(_glthread_TSD *, void *); -#else /* __MSC__ */ +#if defined(GLX_USE_TLS) -typedef int _glthread_Mutex; +extern __thread struct _glapi_table * _glapi_tls_Dispatch + __attribute__((tls_model("initial-exec"))); -#define _glthread_INIT_MUTEX( M ) ((void) (M)) -#define _glthread_LOCK_MUTEX( M ) ((void) (M)) -#define _glthread_UNLOCK_MUTEX( M ) ((void) (M)) +#define GET_DISPATCH() _glapi_tls_Dispatch -#define sched_yield() ((void) 0) +#elif !defined(GL_CALL) +# if defined(THREADS) +# define GET_DISPATCH() \ + ((__builtin_expect( _glapi_Dispatch != NULL, 1 )) \ + ? _glapi_Dispatch : _glapi_get_dispatch()) +# else +# define GET_DISPATCH() _glapi_Dispatch +# endif /* defined(THREADS) */ +#endif /* ndef GL_CALL */ -#endif /* __MSC__ */ -#endif /* P_THREAD_H */ +#endif /* _P_THREAD_H_ */ diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index 525ba580e8..0ad19d42a8 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -35,5 +35,5 @@ drivers = [ env.SharedLibrary( target ='i915tex_dri.so', source = sources, - LIBS = mesa + drivers + auxiliaries + env['LIBS'], + LIBS = drivers + mesa + auxiliaries + env['LIBS'], ) \ No newline at end of file diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c index 33b56817f6..ce154c7b88 100644 --- a/src/gallium/winsys/dri/intel/intel_batchpool.c +++ b/src/gallium/winsys/dri/intel/intel_batchpool.c @@ -36,9 +36,12 @@ #include #include +#include #include -#include "imports.h" -#include "glthread.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_thread.h" + #include "dri_bufpool.h" #include "dri_bufmgr.h" #include "intel_batchpool.h" @@ -196,7 +199,7 @@ pool_create(struct _DriBufferPool *pool, _glthread_LOCK_MUTEX(p->mutex); if (p->numFree == 0) - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); if (p->numFree == 0) { fprintf(stderr, "Out of fixed size buffer objects\n"); @@ -278,7 +281,7 @@ pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, return -EBUSY; } - buf->mapped = GL_TRUE; + buf->mapped = TRUE; *virtual = (unsigned char *) p->virtual + buf->start; _glthread_UNLOCK_MUTEX(p->mutex); return 0; @@ -361,7 +364,7 @@ pool_validate(struct _DriBufferPool *pool, void *private) BBuf *buf = (BBuf *) private; BPool *p = buf->parent; _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = GL_TRUE; + buf->unfenced = TRUE; _glthread_UNLOCK_MUTEX(p->mutex); return 0; } @@ -379,7 +382,7 @@ pool_takedown(struct _DriBufferPool *pool) while ((p->numFree < p->numTot) && p->numDelayed) { _glthread_UNLOCK_MUTEX(p->mutex); sched_yield(); - pool_checkFree(p, GL_TRUE); + pool_checkFree(p, TRUE); _glthread_LOCK_MUTEX(p->mutex); } diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index f8aa5ef945..c38b5be52c 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,6 +3,12 @@ Import('*') +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', +]) sources = [ 'glxapi.c', diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c index 541d50c6e4..10eedd8402 100644 --- a/src/gallium/winsys/xlib/brw_aub.c +++ b/src/gallium/winsys/xlib/brw_aub.c @@ -29,11 +29,13 @@ * Keith Whitwell */ +#include +#include #include "brw_aub.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "imports.h" -//#include "intel_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" struct brw_aubfile { @@ -350,9 +352,9 @@ struct brw_aubfile *brw_aubfile_create( void ) i++; - if (_mesa_getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); - _mesa_printf("--> Aub file: %s\n", filename); + if (getenv("INTEL_AUBFILE")) { + val = snprintf(filename, sizeof(filename), "%s%d.aub", getenv("INTEL_AUBFILE"), i%4); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } else { @@ -360,12 +362,12 @@ struct brw_aubfile *brw_aubfile_create( void ) if (val < 0 || val > sizeof(filename)) strcpy(filename, "default.aub"); - _mesa_printf("--> Aub file: %s\n", filename); + debug_printf("--> Aub file: %s\n", filename); aubfile->file = fopen(filename, "w"); } if (!aubfile->file) { - _mesa_printf("couldn't open aubfile\n"); + debug_printf("couldn't open aubfile\n"); exit(1); } diff --git a/src/mesa/SConscript b/src/mesa/SConscript index a828133580..db18c61fac 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -4,6 +4,13 @@ Import('*') +env = env.Clone() + +# Includes +env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', +]) ####################################################################### # Core sources diff --git a/src/mesa/x86/common_x86_asm.S b/src/mesa/x86/common_x86_asm.S index ef3cc9eb59..09c86b05ba 100644 --- a/src/mesa/x86/common_x86_asm.S +++ b/src/mesa/x86/common_x86_asm.S @@ -39,7 +39,7 @@ * in there will break the build on some platforms. */ -#include "matypes.h" +#include "assyntax.h" #include "common_x86_features.h" SEG_TEXT -- cgit v1.2.3 From d710a7cfb2c129fcb937e40fa9b367d662138bc5 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 19 Feb 2008 18:53:16 +0900 Subject: Windows (DDK) compilation support. It also works when cross compiling with Wine. --- SConstruct | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 6cb07302e8..0420195395 100644 --- a/SConstruct +++ b/SConstruct @@ -28,6 +28,13 @@ import sys # to get the full list of options. See scons manpage for more info. # +platform_map = { + 'linux2': 'linux', + 'win32': 'winddk', +} + +platform = platform_map.get(sys.platform, sys.platform) + # TODO: auto-detect defaults opts = Options('config.py') opts.Add(BoolOption('debug', 'build debug version', False)) @@ -35,6 +42,8 @@ opts.Add(BoolOption('dri', 'build dri drivers', False)) opts.Add(BoolOption('llvm', 'use llvm', False)) opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86', allowed_values=('generic', 'x86', 'x86-64'))) +opts.Add(EnumOption('platform', 'target platform', platform, + allowed_values=('linux', 'cell', 'winddk'))) env = Environment( options = opts, @@ -44,25 +53,17 @@ Help(opts.GenerateHelpText(env)) # for debugging #print env.Dump() -if 0: - # platform will be typically 'posix' or 'win32' - platform = env['PLATFORM'] -else: - # platform will be one of 'linux', 'freebsd', 'win32', 'darwin', etc. - platform = sys.platform - if platform == 'linux2': - platform = 'linux' - # replicate options values in local variables debug = env['debug'] dri = env['dri'] llvm = env['llvm'] machine = env['machine'] +platform = env['platform'] # derived options x86 = machine == 'x86' -gcc = platform in ('posix', 'linux', 'freebsd', 'darwin') -msvc = platform == 'win32' +gcc = platform in ('linux', 'freebsd', 'darwin') +msvc = platform in ('win32', 'winddk') Export([ 'debug', @@ -78,10 +79,32 @@ Export([ ####################################################################### # Environment setup # -# TODO: put the compiler specific settings in seperate files +# TODO: put the compiler specific settings in separate files # TODO: auto-detect as much as possible - + +if platform == 'winddk': + import ntpath + escape = env['ESCAPE'] + env.Tool('msvc') + if 'BASEDIR' in os.environ: + WINDDK = os.environ['BASEDIR'] + else: + WINDDK = "C:\\WINDDK\\3790.1830" + # NOTE: We need this elaborate construct to get the absolute paths and + # forward slashes to msvc unharmed when cross compiling from posix platforms + env.Append(CPPFLAGS = [ + escape('/I' + ntpath.join(WINDDK, 'inc\\ddk\\wxp')), + escape('/I' + ntpath.join(WINDDK, 'inc\\ddk\\wdm\\wxp')), + escape('/I' + ntpath.join(WINDDK, 'inc\\crt')), + ]) + env.Append(CPPDEFINES = [ + ('i386', '1'), + ]) + if debug: + env.Append(CPPDEFINES = ['DBG']) + + # Optimization flags if gcc: if debug: -- cgit v1.2.3 From 26c57d163092d8069c69ff47929e73682b819ab2 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 23 Feb 2008 00:46:40 +0900 Subject: Avoid building problematic module/drivers on windows. --- SConstruct | 30 +++++++++++++++++++++++++----- src/SConscript | 11 ++++++----- src/gallium/SConscript | 9 +++++++-- src/gallium/winsys/SConscript | 3 ++- 4 files changed, 40 insertions(+), 13 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 0420195395..f4438cf546 100644 --- a/SConstruct +++ b/SConstruct @@ -33,17 +33,37 @@ platform_map = { 'win32': 'winddk', } -platform = platform_map.get(sys.platform, sys.platform) +default_platform = platform_map.get(sys.platform, sys.platform) +default_drivers = 'all' +if default_platform in ('linux', 'freebsd', 'darwin'): + default_x11 = 'yes' +else: + default_x11 = 'no' # TODO: auto-detect defaults opts = Options('config.py') opts.Add(BoolOption('debug', 'build debug version', False)) -opts.Add(BoolOption('dri', 'build dri drivers', False)) -opts.Add(BoolOption('llvm', 'use llvm', False)) opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86', allowed_values=('generic', 'x86', 'x86-64'))) -opts.Add(EnumOption('platform', 'target platform', platform, +opts.Add(EnumOption('platform', 'target platform', default_platform, allowed_values=('linux', 'cell', 'winddk'))) +opts.Add(ListOption('statetrackers', 'state_trackers to build', 'all', + [ + 'mesa', + ], + )) +#opts.Add(ListOption('drivers', 'pipe drivers to build', 'all', +# [ +# 'softpipe', +# 'failover', +# 'i915simple', +# 'i965simple', +# 'cell', +# ], +# )) +opts.Add(BoolOption('llvm', 'use llvm', False)) +opts.Add(BoolOption('dri', 'build dri drivers', False)) +opts.Add(BoolOption('x11', 'build x11 driver', default_x11)) env = Environment( options = opts, @@ -114,7 +134,7 @@ if gcc: env.Append(CFLAGS = '-O3 -g3') env.Append(CXXFLAGS = '-O3 -g3') - env.Append(CFLAGS = '-Wall -Wmissing-prototypes -std=c99 -ffast-math -pedantic') + env.Append(CFLAGS = '-Wall -Wmissing-prototypes -Wno-long-long -ffast-math -pedantic') env.Append(CXXFLAGS = '-Wall -pedantic') # Be nice to Eclipse diff --git a/src/SConscript b/src/SConscript index 5b09943894..e2ee50dd6e 100644 --- a/src/SConscript +++ b/src/SConscript @@ -1,7 +1,8 @@ Import('*') -SConscript([ - 'gallium/SConscript', - 'mesa/SConscript', - 'gallium/winsys/SConscript', -]) +SConscript('gallium/SConscript') + +if 'mesa' in env['state_trackers']: + SConscript('mesa/SConscript') + +SConscript('gallium/winsys/SConscript') diff --git a/src/gallium/SConscript b/src/gallium/SConscript index a08b4b830e..210fd7d309 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -23,7 +23,12 @@ if llvm: SConscript([ 'drivers/softpipe/SConscript', 'drivers/i915simple/SConscript', - 'drivers/i965simple/SConscript', 'drivers/failover/SConscript', - #'drivers/cell/SConscript', ]) + +if not msvc: + SConscript(['drivers/i965simple/SConscript']) + +#if cell: +# SConscript(['drivers/cell/SConscript']) + \ No newline at end of file diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 32215d8d58..3f0596e19c 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -4,7 +4,8 @@ if dri: SConscript([ 'dri/SConscript', ]) -else: + +if env['x11'] and not dri and platform != 'winddk': SConscript([ 'xlib/SConscript', ]) -- cgit v1.2.3 From 58a3d7dfd94453c25607106835fbbb3a54d42306 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 23 Feb 2008 19:49:08 +0900 Subject: Revamp scons usage. --- SConstruct | 46 +++++---- src/gallium/SConscript | 16 +-- src/gallium/winsys/SConscript | 2 +- winddk.py | 222 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 256 insertions(+), 30 deletions(-) create mode 100644 winddk.py (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index f4438cf546..02e6165005 100644 --- a/SConstruct +++ b/SConstruct @@ -34,11 +34,18 @@ platform_map = { } default_platform = platform_map.get(sys.platform, sys.platform) -default_drivers = 'all' + if default_platform in ('linux', 'freebsd', 'darwin'): - default_x11 = 'yes' + default_statetrackers = 'mesa' + default_drivers = 'softpipe,failover,i915simple,i965simple' + default_winsys = 'xlib' +elif default_platform in ('winddk',): + default_statetrackers = 'none' + default_drivers = 'softpipe,i915simple' + default_winsys = 'none' else: - default_x11 = 'no' + default_drivers = 'all' + default_winsys = 'all' # TODO: auto-detect defaults opts = Options('config.py') @@ -47,23 +54,28 @@ opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86', allowed_values=('generic', 'x86', 'x86-64'))) opts.Add(EnumOption('platform', 'target platform', default_platform, allowed_values=('linux', 'cell', 'winddk'))) -opts.Add(ListOption('statetrackers', 'state_trackers to build', 'all', +opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetrackers, [ 'mesa', ], )) -#opts.Add(ListOption('drivers', 'pipe drivers to build', 'all', -# [ -# 'softpipe', -# 'failover', -# 'i915simple', -# 'i965simple', -# 'cell', -# ], -# )) -opts.Add(BoolOption('llvm', 'use llvm', False)) -opts.Add(BoolOption('dri', 'build dri drivers', False)) -opts.Add(BoolOption('x11', 'build x11 driver', default_x11)) +opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, + [ + 'softpipe', + 'failover', + 'i915simple', + 'i965simple', + 'cell', + ], + )) +opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, + [ + 'xlib', + 'intel', + ], + )) +opts.Add(BoolOption('llvm', 'use LLVM', 'no')) +opts.Add(BoolOption('dri', 'build DRI drivers', 'no')) env = Environment( options = opts, @@ -106,7 +118,7 @@ Export([ if platform == 'winddk': import ntpath escape = env['ESCAPE'] - env.Tool('msvc') + env.Tool('winddk', '.') if 'BASEDIR' in os.environ: WINDDK = os.environ['BASEDIR'] else: diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 210fd7d309..fa4833cbcf 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -1,3 +1,5 @@ +import os + Import('*') env = env.Clone() @@ -20,15 +22,5 @@ SConscript([ if llvm: SConscript(['auxiliary/gallivm/SConscript']) -SConscript([ - 'drivers/softpipe/SConscript', - 'drivers/i915simple/SConscript', - 'drivers/failover/SConscript', -]) - -if not msvc: - SConscript(['drivers/i965simple/SConscript']) - -#if cell: -# SConscript(['drivers/cell/SConscript']) - \ No newline at end of file +for driver in env['drivers']: + SConscript(os.path.join('drivers', driver, 'SConscript')) diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 3f0596e19c..635a68eea2 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -5,7 +5,7 @@ if dri: 'dri/SConscript', ]) -if env['x11'] and not dri and platform != 'winddk': +if 'xlib' in env['drivers'] and not dri: SConscript([ 'xlib/SConscript', ]) diff --git a/winddk.py b/winddk.py new file mode 100644 index 0000000000..af4335dbb0 --- /dev/null +++ b/winddk.py @@ -0,0 +1,222 @@ +"""engine.SCons.Tool.msvc + +Tool-specific initialization for Microsoft Visual C/C++. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/Tool/msvc.py 2523 2007/12/12 09:37:41 knight" + +import os.path +import re +import string + +import SCons.Action +import SCons.Builder +import SCons.Errors +import SCons.Platform.win32 +import SCons.Tool +import SCons.Tool.mslib +import SCons.Tool.mslink +import SCons.Util +import SCons.Warnings + +CSuffixes = ['.c', '.C'] +CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] + +def get_winddk_paths(env, version=None): + """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values + of those three environment variables that should be set + in order to execute the MSVC tools properly.""" + + WINDDKdir = None + exe_paths = [] + lib_paths = [] + include_paths = [] + + if 'BASEDIR' in os.environ: + WINDDKdir = os.environ['BASEDIR'] + else: + WINDDKdir = "C:\\WINDDK\\3790.1830" + + exe_paths.append( os.path.join(WINDDKdir, 'bin') ) + exe_paths.append( os.path.join(WINDDKdir, 'bin\\x86') ) + include_paths.append( os.path.join(WINDDKdir, 'inc\\wxp') ) + lib_paths.append( os.path.join(WINDDKdir, 'lib') ) + + include_path = string.join( include_paths, os.pathsep ) + lib_path = string.join(lib_paths, os.pathsep ) + exe_path = string.join(exe_paths, os.pathsep ) + return (include_path, lib_path, exe_path) + +def validate_vars(env): + """Validate the PCH and PCHSTOP construction variables.""" + if env.has_key('PCH') and env['PCH']: + if not env.has_key('PCHSTOP'): + raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined." + if not SCons.Util.is_String(env['PCHSTOP']): + raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP'] + +def pch_emitter(target, source, env): + """Adds the object file target.""" + + validate_vars(env) + + pch = None + obj = None + + for t in target: + if SCons.Util.splitext(str(t))[1] == '.pch': + pch = t + if SCons.Util.splitext(str(t))[1] == '.obj': + obj = t + + if not obj: + obj = SCons.Util.splitext(str(pch))[0]+'.obj' + + target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work + + return (target, source) + +def object_emitter(target, source, env, parent_emitter): + """Sets up the PCH dependencies for an object file.""" + + validate_vars(env) + + parent_emitter(target, source, env) + + if env.has_key('PCH') and env['PCH']: + env.Depends(target, env['PCH']) + + return (target, source) + +def static_object_emitter(target, source, env): + return object_emitter(target, source, env, + SCons.Defaults.StaticObjectEmitter) + +def shared_object_emitter(target, source, env): + return object_emitter(target, source, env, + SCons.Defaults.SharedObjectEmitter) + +pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR') +pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch', + emitter=pch_emitter, + source_scanner=SCons.Tool.SourceFileScanner) +res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') +res_builder = SCons.Builder.Builder(action=res_action, + src_suffix='.rc', + suffix='.res', + src_builder=[], + source_scanner=SCons.Tool.SourceFileScanner) +SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) + +def generate(env): + """Add Builders and construction variables for MSVC++ to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCAction) + static_obj.add_emitter(suffix, static_object_emitter) + shared_obj.add_emitter(suffix, shared_object_emitter) + + for suffix in CXXSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CXXAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) + static_obj.add_emitter(suffix, static_object_emitter) + shared_obj.add_emitter(suffix, shared_object_emitter) + + env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}']) + env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}']) + env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS' + env['CC'] = 'cl' + env['CCFLAGS'] = SCons.Util.CLVar('/nologo') + env['CFLAGS'] = SCons.Util.CLVar('') + env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS' + env['SHCC'] = '$CC' + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') + env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') + env['SHCCCOM'] = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS' + env['CXX'] = '$CC' + env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)') + env['CXXCOM'] = '$CXX $CXXFLAGS $CCCOMFLAGS' + env['SHCXX'] = '$CXX' + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') + env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS' + env['CPPDEFPREFIX'] = '/D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '/I' + env['INCSUFFIX'] = '' +# env.Append(OBJEMITTER = [static_object_emitter]) +# env.Append(SHOBJEMITTER = [shared_object_emitter]) + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + + env['RC'] = 'rc' + env['RCFLAGS'] = SCons.Util.CLVar('') + env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES' + env['BUILDERS']['RES'] = res_builder + env['OBJPREFIX'] = '' + env['OBJSUFFIX'] = '.obj' + env['SHOBJPREFIX'] = '$OBJPREFIX' + env['SHOBJSUFFIX'] = '$OBJSUFFIX' + + try: + include_path, lib_path, exe_path = get_winddk_paths(env) + + # since other tools can set these, we just make sure that the + # relevant stuff from MSVS is in there somewhere. + env.PrependENVPath('INCLUDE', include_path) + env.PrependENVPath('LIB', lib_path) + env.PrependENVPath('PATH', exe_path) + except (SCons.Util.RegError, SCons.Errors.InternalError): + pass + + env['CFILESUFFIX'] = '.c' + env['CXXFILESUFFIX'] = '.cc' + + env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}']) + env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS' + env['BUILDERS']['PCH'] = pch_builder + + env['AR'] = 'lib' + env['ARFLAGS'] = SCons.Util.CLVar('/nologo') + env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}" + env['LIBPREFIX'] = '' + env['LIBSUFFIX'] = '.lib' + + SCons.Tool.mslink.generate(env) + + if not env.has_key('ENV'): + env['ENV'] = {} + if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders + env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root() + +def exists(env): + return env.Detect('cl') + -- cgit v1.2.3 From e70a431c3d87a829b3eb1b931d5af365ceee75b5 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 24 Feb 2008 16:43:07 +0900 Subject: A few more tweaks to get correct WINDDK compilation. --- SConstruct | 34 ++++++++++++++++++++++------------ winddk.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 12 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 02e6165005..219997ca91 100644 --- a/SConstruct +++ b/SConstruct @@ -39,13 +39,17 @@ if default_platform in ('linux', 'freebsd', 'darwin'): default_statetrackers = 'mesa' default_drivers = 'softpipe,failover,i915simple,i965simple' default_winsys = 'xlib' + default_dri = 'yes' elif default_platform in ('winddk',): default_statetrackers = 'none' default_drivers = 'softpipe,i915simple' default_winsys = 'none' + default_dri = 'no' else: default_drivers = 'all' default_winsys = 'all' + default_dri = 'no' + # TODO: auto-detect defaults opts = Options('config.py') @@ -75,7 +79,7 @@ opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, ], )) opts.Add(BoolOption('llvm', 'use LLVM', 'no')) -opts.Add(BoolOption('dri', 'build DRI drivers', 'no')) +opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) env = Environment( options = opts, @@ -125,17 +129,23 @@ if platform == 'winddk': WINDDK = "C:\\WINDDK\\3790.1830" # NOTE: We need this elaborate construct to get the absolute paths and # forward slashes to msvc unharmed when cross compiling from posix platforms - env.Append(CPPFLAGS = [ - escape('/I' + ntpath.join(WINDDK, 'inc\\ddk\\wxp')), - escape('/I' + ntpath.join(WINDDK, 'inc\\ddk\\wdm\\wxp')), - escape('/I' + ntpath.join(WINDDK, 'inc\\crt')), - ]) - env.Append(CPPDEFINES = [ - ('i386', '1'), - ]) - if debug: - env.Append(CPPDEFINES = ['DBG']) + #env.Append(CPPFLAGS = [ + # escape('/I' + ntpath.join(WINDDK, 'inc\\wxp')), + # escape('/I' + ntpath.join(WINDDK, 'inc\\ddk\\wxp')), + # escape('/I' + ntpath.join(WINDDK, 'inc\\ddk\\wdm\\wxp')), + # escape('/I' + ntpath.join(WINDDK, 'inc\\crt')), + #]) + env.Append(CFLAGS = '/W3') + if debug: + env.Append(CPPDEFINES = [ + ('DBG', '1'), + ('DEBUG', '1'), + ('_DEBUG', '1'), + ]) + env.Append(CFLAGS = '/Od /Zi') + env.Append(CXXFLAGS = '/Od /Zi') + # Optimization flags if gcc: @@ -224,7 +234,7 @@ if llvm: # libGL -if 1: +if platform not in ('winddk',): env.Append(LIBS = [ 'X11', 'Xext', diff --git a/winddk.py b/winddk.py index af4335dbb0..1a5a0d1aa7 100644 --- a/winddk.py +++ b/winddk.py @@ -212,6 +212,48 @@ def generate(env): SCons.Tool.mslink.generate(env) + # See also: + # - WINDDK's bin/makefile.new for more info. + # - http://alter.org.ua/docs/nt_kernel/vc8_proj/ + env.Append(CPPDEFINES = [ + 'WIN32', + '_WINDOWS', + ('i386', '1'), + ('_X86_', '1'), + 'STD_CALL', + ('CONDITION_HANDLING', '1'), + ('NT_INST', '0'), + ('_NT1X_', '100'), + ('WINNT', '1'), + ('_WIN32_WINNT', '0x0500'), # minimum required OS version + ('WIN32_LEAN_AND_MEAN', '1'), + ('DEVL', '1'), + ('FPO', '1'), + ]) + cflags = [ + '/GF', # Enable String Pooling + #'/EHsc', # Enable C++ Exceptions + '/Zp8', # 8bytes struct member alignment + #'/GS-', # No Buffer Security Check + #'/GR-', # Disable Run-Time Type Info + '/Gz', # __stdcall Calling convention + ] + env.Append(CFLAGS = cflags) + env.Append(CXXFLAGS = cflags) + + env.Append(LINKFLAGS = [ + '/DEBUG', + '/NODEFAULTLIB', + '/SUBSYSTEM:NATIVE', + '/INCREMENTAL:NO', + #'/DRIVER', + + #'-subsystem:native,4.00', + '-base:0x10000', + + '-entry:DrvEnableDriver', + ]) + if not env.has_key('ENV'): env['ENV'] = {} if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders -- cgit v1.2.3 From efd336887f9c46e66b304def0aa5fc5e16dc990f Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 25 Feb 2008 14:46:53 +0900 Subject: Cleanup scons files. --- SConstruct | 23 ++++++++--------------- winddk.py | 20 +++++++++++++++++--- 2 files changed, 25 insertions(+), 18 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 219997ca91..6d88d52f00 100644 --- a/SConstruct +++ b/SConstruct @@ -120,21 +120,14 @@ Export([ if platform == 'winddk': - import ntpath - escape = env['ESCAPE'] - env.Tool('winddk', '.') - if 'BASEDIR' in os.environ: - WINDDK = os.environ['BASEDIR'] - else: - WINDDK = "C:\\WINDDK\\3790.1830" - # NOTE: We need this elaborate construct to get the absolute paths and - # forward slashes to msvc unharmed when cross compiling from posix platforms - #env.Append(CPPFLAGS = [ - # escape('/I' + ntpath.join(WINDDK, 'inc\\wxp')), - # escape('/I' + ntpath.join(WINDDK, 'inc\\ddk\\wxp')), - # escape('/I' + ntpath.join(WINDDK, 'inc\\ddk\\wdm\\wxp')), - # escape('/I' + ntpath.join(WINDDK, 'inc\\crt')), - #]) + env.Tool('winddk', ['.']) + + env.Append(CPPPATH = [ + env['SDK_INC_PATH'], + env['DDK_INC_PATH'], + env['WDM_INC_PATH'], + env['CRT_INC_PATH'], + ]) env.Append(CFLAGS = '/W3') if debug: diff --git a/winddk.py b/winddk.py index a54abf0e92..3dcf9027e5 100644 --- a/winddk.py +++ b/winddk.py @@ -63,13 +63,27 @@ def get_winddk_paths(env, version=None): if 'BASEDIR' in os.environ: WINDDKdir = os.environ['BASEDIR'] else: - WINDDKdir = "C:\\WINDDK\\3790.1830" + #WINDDKdir = "C:\\WINDDK\\3790.1830" + WINDDKdir = "C:/WINDDK/3790.1830" exe_paths.append( os.path.join(WINDDKdir, 'bin') ) - exe_paths.append( os.path.join(WINDDKdir, 'bin\\x86') ) - include_paths.append( os.path.join(WINDDKdir, 'inc\\wxp') ) + exe_paths.append( os.path.join(WINDDKdir, 'bin/x86') ) + include_paths.append( os.path.join(WINDDKdir, 'inc/wxp') ) lib_paths.append( os.path.join(WINDDKdir, 'lib') ) + target_os = 'wxp' + target_cpu = 'i386' + + env['SDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', target_os) + env['CRT_INC_PATH'] = os.path.join(WINDDKdir, 'inc/crt') + env['DDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc/ddk', target_os) + env['WDM_INC_PATH'] = os.path.join(WINDDKdir, 'inc/ddk/wdm', target_os) + + env['SDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) + env['CRT_LIB_PATH'] = os.path.join(WINDDKdir, 'lib/crt', target_cpu) + env['DDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) + env['WDM_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) + include_path = string.join( include_paths, os.pathsep ) lib_path = string.join(lib_paths, os.pathsep ) exe_path = string.join(exe_paths, os.pathsep ) -- cgit v1.2.3 From c8b069cc1e839b5dd7a11d33c291b6b587a45df3 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 25 Feb 2008 17:55:45 +0900 Subject: Get more debugging info out of MSVC. --- SConstruct | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 6d88d52f00..e4926f29b6 100644 --- a/SConstruct +++ b/SConstruct @@ -128,17 +128,6 @@ if platform == 'winddk': env['WDM_INC_PATH'], env['CRT_INC_PATH'], ]) - - env.Append(CFLAGS = '/W3') - if debug: - env.Append(CPPDEFINES = [ - ('DBG', '1'), - ('DEBUG', '1'), - ('_DEBUG', '1'), - ]) - env.Append(CFLAGS = '/Od /Zi') - env.Append(CXXFLAGS = '/Od /Zi') - # Optimization flags if gcc: @@ -156,10 +145,34 @@ if gcc: env.Append(CFLAGS = '-fmessage-length=0') env.Append(CXXFLAGS = '-fmessage-length=0') +if msvc: + env.Append(CFLAGS = '/W3') + if debug: + cflags = [ + '/Od', # disable optimizations + '/Oy-', # disable frame pointer omission + '/Zi', # enable enable debugging information + ] + else: + cflags = [ + '/Ox', # maximum optimizations + '/Os', # favor code space + '/Zi', # enable enable debugging information + ] + env.Append(CFLAGS = cflags) + env.Append(CXXFLAGS = cflags) + # Defines if debug: - env.Append(CPPDEFINES = ['DEBUG']) + if gcc: + env.Append(CPPDEFINES = ['DEBUG']) + if msvc: + env.Append(CPPDEFINES = [ + ('DBG', '1'), + ('DEBUG', '1'), + ('_DEBUG', '1'), + ]) else: env.Append(CPPDEFINES = ['NDEBUG']) -- cgit v1.2.3 From 6d336588edb8318f49a0f611760e7ff8b6861de7 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 26 Feb 2008 22:31:03 +0900 Subject: scons: Properly generate PDB files on MSVC. --- SConstruct | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index e4926f29b6..393936b4c8 100644 --- a/SConstruct +++ b/SConstruct @@ -151,17 +151,17 @@ if msvc: cflags = [ '/Od', # disable optimizations '/Oy-', # disable frame pointer omission - '/Zi', # enable enable debugging information ] else: cflags = [ '/Ox', # maximum optimizations '/Os', # favor code space - '/Zi', # enable enable debugging information ] env.Append(CFLAGS = cflags) env.Append(CXXFLAGS = cflags) - + # Put debugging information in a separate .pdb file for each object file as + # descrived in the scons manpage + env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' # Defines if debug: -- cgit v1.2.3 From 19f6e1a975a098cf4ce935b50f7cf0c64d9db042 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 26 Feb 2008 23:59:53 +0900 Subject: scons: Prefer MSVS 2003 (patch by Mark Mueller). --- SConstruct | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 393936b4c8..fbf5aa0e4e 100644 --- a/SConstruct +++ b/SConstruct @@ -146,6 +146,13 @@ if gcc: env.Append(CXXFLAGS = '-fmessage-length=0') if msvc: + # Force msvc 7.1 (visual studio 2003) for windows builds. + # Eventually a way to override this would be nice. + # See also http://www.scons.org/wiki/MsvsMultipleVersions + env["MSVS"] = {"VERSION": "7.1"} + env["MSVS_VERSION"] = "7.1" + Tool("msvc")(env) + env.Append(CFLAGS = '/W3') if debug: cflags = [ -- cgit v1.2.3 From a6044bdf74bae96f05310ad6e39942f172b8ab02 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 27 Feb 2008 09:10:14 +0900 Subject: Revert "scons: Prefer MSVS 2003 (patch by Mark Mueller)." This reverts commit 19f6e1a975a098cf4ce935b50f7cf0c64d9db042. --- SConstruct | 7 ------- 1 file changed, 7 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index fbf5aa0e4e..393936b4c8 100644 --- a/SConstruct +++ b/SConstruct @@ -146,13 +146,6 @@ if gcc: env.Append(CXXFLAGS = '-fmessage-length=0') if msvc: - # Force msvc 7.1 (visual studio 2003) for windows builds. - # Eventually a way to override this would be nice. - # See also http://www.scons.org/wiki/MsvsMultipleVersions - env["MSVS"] = {"VERSION": "7.1"} - env["MSVS_VERSION"] = "7.1" - Tool("msvc")(env) - env.Append(CFLAGS = '/W3') if debug: cflags = [ -- cgit v1.2.3 From 67099cd7b96dca5ee0e88543b7fc316f6535ea8f Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 27 Feb 2008 16:53:52 +0900 Subject: scons: Autodetect the default machine. --- SConstruct | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 393936b4c8..c9a4031fbb 100644 --- a/SConstruct +++ b/SConstruct @@ -4,6 +4,7 @@ import os import os.path import sys +import platform as _platform ####################################################################### @@ -32,8 +33,22 @@ platform_map = { 'linux2': 'linux', 'win32': 'winddk', } - -default_platform = platform_map.get(sys.platform, sys.platform) +default_platform = sys.platform +default_platform = platform_map.get(default_platform, default_platform) + +machine_map = { + 'x86': 'x86', + 'i386': 'x86', + 'i486': 'x86', + 'i586': 'x86', + 'i686': 'x86', + 'x86_64': 'x86_64', +} +if 'PROCESSOR_ARCHITECTURE' in os.environ: + default_machine = os.environ['PROCESSOR_ARCHITECTURE'] +else: + default_machine = _platform.machine() +default_machine = machine_map.get(default_machine, 'generic') if default_platform in ('linux', 'freebsd', 'darwin'): default_statetrackers = 'mesa' @@ -53,9 +68,9 @@ else: # TODO: auto-detect defaults opts = Options('config.py') -opts.Add(BoolOption('debug', 'build debug version', False)) -opts.Add(EnumOption('machine', 'use machine-specific assembly code', 'x86', - allowed_values=('generic', 'x86', 'x86-64'))) +opts.Add(BoolOption('debug', 'build debug version', 'no')) +opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, + allowed_values=('generic', 'x86', 'x86_64'))) opts.Add(EnumOption('platform', 'target platform', default_platform, allowed_values=('linux', 'cell', 'winddk'))) opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetrackers, @@ -296,8 +311,8 @@ if dri: build_subdir += "-dri" if llvm: build_subdir += "-llvm" -if x86: - build_subdir += "-x86" +if env['machine'] != 'generic': + build_subdir += '-' + env['machine'] if debug: build_subdir += "-debug" build_dir = os.path.join(build_topdir, build_subdir) -- cgit v1.2.3 From 9409043c58bbcac37b439032fc61aff2a0b0d543 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 27 Feb 2008 17:36:28 +0900 Subject: scons: Move common code to a separate file. --- SConstruct | 124 +++++++++---------------------------------------------------- common.py | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 106 deletions(-) create mode 100644 common.py (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index c9a4031fbb..8013e7c3b2 100644 --- a/SConstruct +++ b/SConstruct @@ -1,14 +1,5 @@ ####################################################################### # Top-level SConstruct - -import os -import os.path -import sys -import platform as _platform - - -####################################################################### -# Configuration options # # For example, invoke scons as # @@ -29,33 +20,21 @@ import platform as _platform # to get the full list of options. See scons manpage for more info. # -platform_map = { - 'linux2': 'linux', - 'win32': 'winddk', -} -default_platform = sys.platform -default_platform = platform_map.get(default_platform, default_platform) - -machine_map = { - 'x86': 'x86', - 'i386': 'x86', - 'i486': 'x86', - 'i586': 'x86', - 'i686': 'x86', - 'x86_64': 'x86_64', -} -if 'PROCESSOR_ARCHITECTURE' in os.environ: - default_machine = os.environ['PROCESSOR_ARCHITECTURE'] -else: - default_machine = _platform.machine() -default_machine = machine_map.get(default_machine, 'generic') +import os +import os.path +import sys + +import common + +####################################################################### +# Configuration options -if default_platform in ('linux', 'freebsd', 'darwin'): +if common.default_platform in ('linux', 'freebsd', 'darwin'): default_statetrackers = 'mesa' default_drivers = 'softpipe,failover,i915simple,i965simple' default_winsys = 'xlib' default_dri = 'yes' -elif default_platform in ('winddk',): +elif common.default_platform in ('winddk',): default_statetrackers = 'none' default_drivers = 'softpipe,i915simple' default_winsys = 'none' @@ -65,36 +44,13 @@ else: default_winsys = 'all' default_dri = 'no' - -# TODO: auto-detect defaults -opts = Options('config.py') -opts.Add(BoolOption('debug', 'build debug version', 'no')) -opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, - allowed_values=('generic', 'x86', 'x86_64'))) -opts.Add(EnumOption('platform', 'target platform', default_platform, - allowed_values=('linux', 'cell', 'winddk'))) +opts = common.Options() opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetrackers, - [ - 'mesa', - ], - )) + ['mesa'])) opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, - [ - 'softpipe', - 'failover', - 'i915simple', - 'i965simple', - 'cell', - ], - )) + ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell'])) opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, - [ - 'xlib', - 'intel', - ], - )) -opts.Add(BoolOption('llvm', 'use LLVM', 'no')) -opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) + ['xlib', 'intel'])) env = Environment( options = opts, @@ -264,64 +220,20 @@ if platform not in ('winddk',): 'Xfixes', ]) -Export('env') - - -####################################################################### -# Convenience Library Builder -# based on the stock StaticLibrary and SharedLibrary builders - -def createConvenienceLibBuilder(env): - """This is a utility function that creates the ConvenienceLibrary - Builder in an Environment if it is not there already. - - If it is already there, we return the existing one. - """ - - try: - convenience_lib = env['BUILDERS']['ConvenienceLibrary'] - except KeyError: - action_list = [ Action("$ARCOM", "$ARCOMSTR") ] - if env.Detect('ranlib'): - ranlib_action = Action("$RANLIBCOM", "$RANLIBCOMSTR") - action_list.append(ranlib_action) +# Convenience library support +common.createConvenienceLibBuilder(env) - convenience_lib = Builder(action = action_list, - emitter = '$LIBEMITTER', - prefix = '$LIBPREFIX', - suffix = '$LIBSUFFIX', - src_suffix = '$SHOBJSUFFIX', - src_builder = 'SharedObject') - env['BUILDERS']['ConvenienceLibrary'] = convenience_lib - env['BUILDERS']['Library'] = convenience_lib - - return convenience_lib - -createConvenienceLibBuilder(env) +Export('env') ####################################################################### # Invoke SConscripts -# Put build output in a separate dir, which depends on the current configuration -# See also http://www.scons.org/wiki/AdvancedBuildExample -build_topdir = 'build' -build_subdir = platform -if dri: - build_subdir += "-dri" -if llvm: - build_subdir += "-llvm" -if env['machine'] != 'generic': - build_subdir += '-' + env['machine'] -if debug: - build_subdir += "-debug" -build_dir = os.path.join(build_topdir, build_subdir) - # TODO: Build several variants at the same time? # http://www.scons.org/wiki/SimultaneousVariantBuilds SConscript( 'src/SConscript', - build_dir = build_dir, + build_dir = common.make_build_dir(env), duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html ) diff --git a/common.py b/common.py new file mode 100644 index 0000000000..e2650d6c8e --- /dev/null +++ b/common.py @@ -0,0 +1,113 @@ +####################################################################### +# Common SCons code + +import os +import os.path +import sys +import platform as _platform + + +####################################################################### +# Defaults + +_platform_map = { + 'linux2': 'linux', + 'win32': 'winddk', +} + +default_platform = sys.platform +default_platform = _platform_map.get(default_platform, default_platform) + +_machine_map = { + 'x86': 'x86', + 'i386': 'x86', + 'i486': 'x86', + 'i586': 'x86', + 'i686': 'x86', + 'x86_64': 'x86_64', +} +if 'PROCESSOR_ARCHITECTURE' in os.environ: + default_machine = os.environ['PROCESSOR_ARCHITECTURE'] +else: + default_machine = _platform.machine() +default_machine = _machine_map.get(default_machine, 'generic') + +if default_platform in ('linux', 'freebsd', 'darwin'): + default_dri = 'yes' +elif default_platform in ('winddk',): + default_dri = 'no' +else: + default_dri = 'no' + + +####################################################################### +# Common options + +def Options(): + from SCons.Options import Options + from SCons.Options.BoolOption import BoolOption + from SCons.Options.EnumOption import EnumOption + opts = Options('config.py') + opts.Add(BoolOption('debug', 'build debug version', 'no')) + opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, + allowed_values=('generic', 'x86', 'x86_64'))) + opts.Add(EnumOption('platform', 'target platform', default_platform, + allowed_values=('linux', 'cell', 'winddk'))) + opts.Add(BoolOption('llvm', 'use LLVM', 'no')) + opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) + return opts + + +####################################################################### +# Convenience Library Builder +# based on the stock StaticLibrary and SharedLibrary builders + +import SCons.Action +import SCons.Builder + +def createConvenienceLibBuilder(env): + """This is a utility function that creates the ConvenienceLibrary + Builder in an Environment if it is not there already. + + If it is already there, we return the existing one. + """ + + try: + convenience_lib = env['BUILDERS']['ConvenienceLibrary'] + except KeyError: + action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] + if env.Detect('ranlib'): + ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") + action_list.append(ranlib_action) + + convenience_lib = SCons.Builder.Builder(action = action_list, + emitter = '$LIBEMITTER', + prefix = '$LIBPREFIX', + suffix = '$LIBSUFFIX', + src_suffix = '$SHOBJSUFFIX', + src_builder = 'SharedObject') + env['BUILDERS']['ConvenienceLibrary'] = convenience_lib + env['BUILDERS']['Library'] = convenience_lib + + return convenience_lib + + +####################################################################### +# Build + +def make_build_dir(env): + # Put build output in a separate dir, which depends on the current configuration + # See also http://www.scons.org/wiki/AdvancedBuildExample + build_topdir = 'build' + build_subdir = env['platform'] + if env['dri']: + build_subdir += "-dri" + if env['llvm']: + build_subdir += "-llvm" + if env['machine'] != 'generic': + build_subdir += '-' + env['machine'] + if env['debug']: + build_subdir += "-debug" + build_dir = os.path.join(build_topdir, build_subdir) + return build_dir + -- cgit v1.2.3 From 13174c195e057f443b23df788ea0c10251942189 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 3 Mar 2008 18:52:37 +0100 Subject: scons: Make command line arguments effective again. --- SConstruct | 6 ++---- common.py | 5 +---- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 8013e7c3b2..6f95d123ff 100644 --- a/SConstruct +++ b/SConstruct @@ -33,18 +33,16 @@ if common.default_platform in ('linux', 'freebsd', 'darwin'): default_statetrackers = 'mesa' default_drivers = 'softpipe,failover,i915simple,i965simple' default_winsys = 'xlib' - default_dri = 'yes' elif common.default_platform in ('winddk',): default_statetrackers = 'none' default_drivers = 'softpipe,i915simple' default_winsys = 'none' - default_dri = 'no' else: default_drivers = 'all' default_winsys = 'all' - default_dri = 'no' -opts = common.Options() +opts = Options('config.py') +common.AddOptions(opts) opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetrackers, ['mesa'])) opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, diff --git a/common.py b/common.py index b65ed7eaaa..1e5f7dad39 100644 --- a/common.py +++ b/common.py @@ -43,11 +43,9 @@ else: ####################################################################### # Common options -def Options(): - from SCons.Options import Options +def AddOptions(opts): from SCons.Options.BoolOption import BoolOption from SCons.Options.EnumOption import EnumOption - opts = Options('config.py') opts.Add(BoolOption('debug', 'build debug version', 'no')) opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, allowed_values=('generic', 'x86', 'x86_64'))) @@ -55,7 +53,6 @@ def Options(): allowed_values=('linux', 'cell', 'winddk'))) opts.Add(BoolOption('llvm', 'use LLVM', 'no')) opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) - return opts ####################################################################### -- cgit v1.2.3 From 9a7679811215a5cae2b4091f2fcda0a2faf4217d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 4 Mar 2008 12:40:18 +0100 Subject: scons: Force C++ linkage. We have some C++ code (LLVM), which must be linked with g++ on certain platforms. SCons tries to guess when to use g++ by looking to the source files, but this fails, if the C++ code is not list in the command line, but inside in the library. --- SConstruct | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 6f95d123ff..dd118dfbb8 100644 --- a/SConstruct +++ b/SConstruct @@ -206,7 +206,10 @@ if llvm: env.ParseConfig('llvm-config --cflags --ldflags --libs') env.Append(CPPDEFINES = ['MESA_LLVM']) env.Append(CXXFLAGS = ['-Wno-long-long']) - + +# Force C++ linkage +if env['PLATFORM'] in ('posix',): + env['LINK'] = env['CXX'] # libGL if platform not in ('winddk',): -- cgit v1.2.3 From 72c9d4a660e5dd7e2bdb5ccb917388f138adae58 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Tue, 4 Mar 2008 18:28:23 +0100 Subject: gallium: Only use C++ compiler for linking when using LLVM. Otherwise, the shared objects needlessly link against the C++ runtime environment. --- SConstruct | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index dd118dfbb8..44ac0ad60d 100644 --- a/SConstruct +++ b/SConstruct @@ -206,9 +206,7 @@ if llvm: env.ParseConfig('llvm-config --cflags --ldflags --libs') env.Append(CPPDEFINES = ['MESA_LLVM']) env.Append(CXXFLAGS = ['-Wno-long-long']) - -# Force C++ linkage -if env['PLATFORM'] in ('posix',): + # Force C++ linkage env['LINK'] = env['CXX'] # libGL -- cgit v1.2.3 From 5aa108214a21181406ec38a2fd5e82a279348f77 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 4 Mar 2008 14:29:27 +0100 Subject: scons: Preliminary code for quieting command lines. --- SConstruct | 7 +------ common.py | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 44ac0ad60d..6088128010 100644 --- a/SConstruct +++ b/SConstruct @@ -55,9 +55,6 @@ env = Environment( ENV = os.environ) Help(opts.GenerateHelpText(env)) -# for debugging -#print env.Dump() - # replicate options values in local variables debug = env['debug'] dri = env['dri'] @@ -87,6 +84,7 @@ Export([ # TODO: put the compiler specific settings in separate files # TODO: auto-detect as much as possible +common.generate(env) if platform == 'winddk': env.Tool('winddk', ['.']) @@ -219,9 +217,6 @@ if platform not in ('winddk',): 'Xfixes', ]) -# Convenience library support -common.createConvenienceLibBuilder(env) - Export('env') diff --git a/common.py b/common.py index 1e5f7dad39..b836a8b41d 100644 --- a/common.py +++ b/common.py @@ -47,6 +47,7 @@ def AddOptions(opts): from SCons.Options.BoolOption import BoolOption from SCons.Options.EnumOption import EnumOption opts.Add(BoolOption('debug', 'build debug version', 'no')) + #opts.Add(BoolOption('quiet', 'quiet command lines', 'no')) opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, allowed_values=('generic', 'x86', 'x86_64'))) opts.Add(EnumOption('platform', 'target platform', default_platform, @@ -55,6 +56,19 @@ def AddOptions(opts): opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) +####################################################################### +# Quiet command lines +# +# See also http://www.scons.org/wiki/HidingCommandLinesInOutput + +def quietCommandLines(env): + env['CCCOMSTR'] = "Compiling $SOURCE ..." + env['CXXCOMSTR'] = "Compiling $SOURCE ..." + env['ARCOMSTR'] = "Archiving $TARGET ..." + env['RANLIBCOMSTR'] = "" + env['LINKCOMSTR'] = "Linking $TARGET ..." + + ####################################################################### # Convenience Library Builder # based on the stock StaticLibrary and SharedLibrary builders @@ -111,3 +125,16 @@ def make_build_dir(env): env.SConsignFile(os.path.join(build_dir, '.sconsign')) return build_dir + +####################################################################### +# Common environment generation code + +def generate(env): + # FIXME: this is already too late + #if env.get('quiet', False): + # quietCommandLines(env) + createConvenienceLibBuilder(env) + + # for debugging + #print env.Dump() + -- cgit v1.2.3 From 4f17bd270e23b7912f0634c2106ea146c9ddd1ee Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 12 Mar 2008 13:34:30 +0000 Subject: scons: Faithfully mimic every WINDDK builtin compiler/linker option. --- SConstruct | 26 +++-------- winddk.py | 142 +++++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 108 insertions(+), 60 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 6088128010..4785e39ec5 100644 --- a/SConstruct +++ b/SConstruct @@ -113,17 +113,9 @@ if gcc: env.Append(CXXFLAGS = '-fmessage-length=0') if msvc: - env.Append(CFLAGS = '/W3') - if debug: - cflags = [ - '/Od', # disable optimizations - '/Oy-', # disable frame pointer omission - ] - else: - cflags = [ - '/Ox', # maximum optimizations - '/Os', # favor code space - ] + cflags = [ + #'/Wp64', # enable 64 bit porting warnings + ] env.Append(CFLAGS = cflags) env.Append(CXXFLAGS = cflags) # Put debugging information in a separate .pdb file for each object file as @@ -132,14 +124,7 @@ if msvc: # Defines if debug: - if gcc: - env.Append(CPPDEFINES = ['DEBUG']) - if msvc: - env.Append(CPPDEFINES = [ - ('DBG', '1'), - ('DEBUG', '1'), - ('_DEBUG', '1'), - ]) + env.Append(CPPDEFINES = ['DEBUG']) else: env.Append(CPPDEFINES = ['NDEBUG']) @@ -217,6 +202,9 @@ if platform not in ('winddk',): 'Xfixes', ]) +# for debugging +#print env.Dump() + Export('env') diff --git a/winddk.py b/winddk.py index d29399f29d..c112329cd6 100644 --- a/winddk.py +++ b/winddk.py @@ -89,6 +89,105 @@ def get_winddk_paths(env, version=None): exe_path = string.join(exe_paths, os.pathsep ) return (include_path, lib_path, exe_path) +def set_winddk_flags(env): + """Mimic WINDDK's builtin flags. + + See also: + - WINDDK's bin/makefile.new i386mk.inc for more info. + - buildchk_wxp_x86.log files, generated by the WINDDK's build + - http://alter.org.ua/docs/nt_kernel/vc8_proj/ + """ + + cppdefines = [ + ('_X86_', '1'), + ('i386', '1'), + 'STD_CALL', + ('CONDITION_HANDLING', '1'), + ('NT_INST', '0'), + ('WIN32', '100'), + ('_NT1X_', '100'), + ('WINNT', '1'), + ('_WIN32_WINNT', '0x0501'), # minimum required OS version + ('WINVER', '0x0501'), + ('_WIN32_IE', '0x0603'), + ('WIN32_LEAN_AND_MEAN', '1'), + ('DEVL', '1'), + ('__BUILDMACHINE__', 'WinDDK'), + ('FPO', '0'), + ] + if env.get('DEBUG', False): + cppdefines += [ + ('DBG', 1), + ] + env.Append(CPPDEFINES = cppdefines) + + # See also: + # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx + # - cl /? + cflags = [ + '/Zl', # omit default library name in .OBJ + '/Zp8', # 8bytes struct member alignment + '/Gy', # separate functions for linker + '/Gm-', # disable minimal rebuild + '/W3', # warning level + '/WX', # treat warnings as errors + '/Gz', # __stdcall Calling convention + '/GX-', # disable C++ EH + '/GR-', # disable C++ RTTI + '/GF', # enable read-only string pooling + '/GS', # enable security checks + '/G6', # optimize for PPro, P-II, P-III + '/Ze', # enable extensions + #'/Gi-', # ??? + '/QIfdiv-', # disable Pentium FDIV fix + #'/hotpatch', # ??? + #'/Z7', #enable old-style debug info + ] + if env.get('debug', False): + cflags += [ + '/Od', # disable optimizations + '/Oi', # enable intrinsic functions + '/Oy-', # disable frame pointer omission + ] + else: + cflags += [ + '/Ox', # maximum optimizations + '/Oi', # enable intrinsic functions + '/Os', # favor code space + ] + env.Append(CFLAGS = cflags) + env.Append(CXXFLAGS = cflags) + + # See also: + # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx + env.Append(LINKFLAGS = [ + '/merge:_PAGE=PAGE', + '/merge:_TEXT=.text', + '/section:INIT,d', + '/opt:ref', + '/opt:icf', + '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221', + '/incremental:no', + '/fullbuild', + '/release', + '/nodefaultlib', + '/wx', + '/debug', + '/debugtype:cv', + '/version:5.1', + '/osversion:5.1', + '/functionpadmin:5', + '/safeseh', + '/pdbcompress', + '/stack:0x40000,0x1000', + '/driver', + '/align:0x80', + '/subsystem:native,5.01', + '/base:0x10000', + + '/entry:DrvEnableDriver', + ]) + def validate_vars(env): """Validate the PCH and PCHSTOP construction variables.""" if env.has_key('PCH') and env['PCH']: @@ -215,47 +314,7 @@ def generate(env): SCons.Tool.mslink.generate(env) - # See also: - # - WINDDK's bin/makefile.new i386mk.inc for more info. - # - http://alter.org.ua/docs/nt_kernel/vc8_proj/ - env.Append(CPPDEFINES = [ - 'WIN32', - '_WINDOWS', - ('i386', '1'), - ('_X86_', '1'), - 'STD_CALL', - ('CONDITION_HANDLING', '1'), - ('NT_INST', '0'), - ('_NT1X_', '100'), - ('WINNT', '1'), - ('_WIN32_WINNT', '0x0500'), # minimum required OS version - ('WIN32_LEAN_AND_MEAN', '1'), - ('DEVL', '1'), - ('FPO', '1'), - ]) - cflags = [ - '/GF', # Enable String Pooling - '/GX-', # Disable C++ Exceptions - '/Zp8', # 8bytes struct member alignment - #'/GS-', # No Buffer Security Check - '/GR-', # Disable Run-Time Type Info - '/Gz', # __stdcall Calling convention - ] - env.Append(CFLAGS = cflags) - env.Append(CXXFLAGS = cflags) - - env.Append(LINKFLAGS = [ - '/DEBUG', - '/NODEFAULTLIB', - '/SUBSYSTEM:NATIVE', - '/INCREMENTAL:NO', - #'/DRIVER', - - #'-subsystem:native,4.00', - '-base:0x10000', - - '-entry:DrvEnableDriver', - ]) + set_winddk_flags(env) if not env.has_key('ENV'): env['ENV'] = {} @@ -275,3 +334,4 @@ def generate(env): def exists(env): return env.Detect('cl') +# vim:set sw=4 et: -- cgit v1.2.3 From 35460fc91cf5311a4cbaee3c577ad8a95ccab1a1 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 25 Apr 2008 18:16:25 +0900 Subject: scons: Teach scons about user-land windows. Actually, more like get rid of all our hacks when compiling for user-land windows. Only MSVC is supported atm though. --- SConstruct | 37 +------------- common.py | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- winddk.py | 101 --------------------------------------- 3 files changed, 158 insertions(+), 139 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 4785e39ec5..9b46e6ade2 100644 --- a/SConstruct +++ b/SConstruct @@ -65,7 +65,7 @@ platform = env['platform'] # derived options x86 = machine == 'x86' gcc = platform in ('linux', 'freebsd', 'darwin') -msvc = platform in ('win32', 'winddk') +msvc = platform in ('windows', 'winddk') Export([ 'debug', @@ -84,8 +84,6 @@ Export([ # TODO: put the compiler specific settings in separate files # TODO: auto-detect as much as possible -common.generate(env) - if platform == 'winddk': env.Tool('winddk', ['.']) @@ -96,37 +94,7 @@ if platform == 'winddk': env['CRT_INC_PATH'], ]) -# Optimization flags -if gcc: - if debug: - env.Append(CFLAGS = '-O0 -g3') - env.Append(CXXFLAGS = '-O0 -g3') - else: - env.Append(CFLAGS = '-O3 -g3') - env.Append(CXXFLAGS = '-O3 -g3') - - env.Append(CFLAGS = '-Wall -Wmissing-prototypes -Wno-long-long -ffast-math -pedantic') - env.Append(CXXFLAGS = '-Wall -pedantic') - - # Be nice to Eclipse - env.Append(CFLAGS = '-fmessage-length=0') - env.Append(CXXFLAGS = '-fmessage-length=0') - -if msvc: - cflags = [ - #'/Wp64', # enable 64 bit porting warnings - ] - env.Append(CFLAGS = cflags) - env.Append(CXXFLAGS = cflags) - # Put debugging information in a separate .pdb file for each object file as - # descrived in the scons manpage - env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' - -# Defines -if debug: - env.Append(CPPDEFINES = ['DEBUG']) -else: - env.Append(CPPDEFINES = ['NDEBUG']) +common.generate(env) # Includes @@ -188,7 +156,6 @@ if llvm: # See also http://www.scons.org/wiki/UsingPkgConfig env.ParseConfig('llvm-config --cflags --ldflags --libs') env.Append(CPPDEFINES = ['MESA_LLVM']) - env.Append(CXXFLAGS = ['-Wno-long-long']) # Force C++ linkage env['LINK'] = env['CXX'] diff --git a/common.py b/common.py index b836a8b41d..51cbd90f1d 100644 --- a/common.py +++ b/common.py @@ -34,7 +34,7 @@ default_machine = _machine_map.get(default_machine, 'generic') if default_platform in ('linux', 'freebsd', 'darwin'): default_dri = 'yes' -elif default_platform in ('winddk',): +elif default_platform in ('winddk', 'windows'): default_dri = 'no' else: default_dri = 'no' @@ -51,7 +51,7 @@ def AddOptions(opts): opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, allowed_values=('generic', 'x86', 'x86_64'))) opts.Add(EnumOption('platform', 'target platform', default_platform, - allowed_values=('linux', 'cell', 'winddk'))) + allowed_values=('linux', 'cell', 'windows', 'winddk'))) opts.Add(BoolOption('llvm', 'use LLVM', 'no')) opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) @@ -133,8 +133,161 @@ def generate(env): # FIXME: this is already too late #if env.get('quiet', False): # quietCommandLines(env) - createConvenienceLibBuilder(env) + + # shortcuts + debug = env['debug'] + machine = env['machine'] + platform = env['platform'] + x86 = env['machine'] == 'x86' + gcc = env['platform'] in ('linux', 'freebsd', 'darwin') + msvc = env['platform'] in ('windows', 'winddk') + + # C preprocessor options + cppdefines = [] + if debug: + cppdefines += ['DEBUG'] + else: + cppdefines += ['NDEBUG'] + if platform == 'windows': + cppdefines += [ + 'WIN32', + '_WINDOWS', + '_UNICODE', + 'UNICODE', + # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx, + 'WIN32_LEAN_AND_MEAN', + 'VC_EXTRALEAN', + ] + if debug: + cppdefines += ['_DEBUG'] + if platform == 'winddk': + # Mimic WINDDK's builtin flags. See also: + # - WINDDK's bin/makefile.new i386mk.inc for more info. + # - buildchk_wxp_x86.log files, generated by the WINDDK's build + # - http://alter.org.ua/docs/nt_kernel/vc8_proj/ + cppdefines += [ + ('_X86_', '1'), + ('i386', '1'), + 'STD_CALL', + ('CONDITION_HANDLING', '1'), + ('NT_INST', '0'), + ('WIN32', '100'), + ('_NT1X_', '100'), + ('WINNT', '1'), + ('_WIN32_WINNT', '0x0501'), # minimum required OS version + ('WINVER', '0x0501'), + ('_WIN32_IE', '0x0603'), + ('WIN32_LEAN_AND_MEAN', '1'), + ('DEVL', '1'), + ('__BUILDMACHINE__', 'WinDDK'), + ('FPO', '0'), + ] + if debug: + cppdefines += [('DBG', 1)] + if platform == 'windows': + cppdefines += ['PIPE_SUBSYSTEM_USER'] + if platform == 'winddk': + cppdefines += ['PIPE_SUBSYSTEM_KERNEL'] + env.Append(CPPDEFINES = cppdefines) + + # C compiler options + cflags = [] + if gcc: + if debug: + cflags += ['-O0', '-g3'] + else: + cflags += ['-O3', '-g3'] + cflags += [ + '-Wall', + '-Wmissing-prototypes', + '-Wno-long-long', + '-ffast-math', + '-pedantic', + '-fmessage-length=0', # be nice to Eclipse + ] + if msvc: + # See also: + # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx + # - cl /? + if debug: + cflags += [ + '/Od', # disable optimizations + '/Oi', # enable intrinsic functions + '/Oy-', # disable frame pointer omission + ] + else: + cflags += [ + '/Ox', # maximum optimizations + '/Oi', # enable intrinsic functions + '/Os', # favor code space + ] + if platform == 'windows': + cflags += [ + # TODO + #'/Wp64', # enable 64 bit porting warnings + ] + if platform == 'winddk': + cflags += [ + '/Zl', # omit default library name in .OBJ + '/Zp8', # 8bytes struct member alignment + '/Gy', # separate functions for linker + '/Gm-', # disable minimal rebuild + '/W3', # warning level + '/WX', # treat warnings as errors + '/Gz', # __stdcall Calling convention + '/GX-', # disable C++ EH + '/GR-', # disable C++ RTTI + '/GF', # enable read-only string pooling + '/GS', # enable security checks + '/G6', # optimize for PPro, P-II, P-III + '/Ze', # enable extensions + #'/Gi-', # ??? + '/QIfdiv-', # disable Pentium FDIV fix + #'/hotpatch', # ??? + #'/Z7', #enable old-style debug info + ] + # Put debugging information in a separate .pdb file for each object file as + # descrived in the scons manpage + env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' + env.Append(CFLAGS = cflags) + env.Append(CXXFLAGS = cflags) + # Linker options + if platform == 'winddk': + # See also: + # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx + env.Append(LINKFLAGS = [ + '/merge:_PAGE=PAGE', + '/merge:_TEXT=.text', + '/section:INIT,d', + '/opt:ref', + '/opt:icf', + '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221', + '/incremental:no', + '/fullbuild', + '/release', + '/nodefaultlib', + '/wx', + '/debug', + '/debugtype:cv', + '/version:5.1', + '/osversion:5.1', + '/functionpadmin:5', + '/safeseh', + '/pdbcompress', + '/stack:0x40000,0x1000', + '/driver', + '/align:0x80', + '/subsystem:native,5.01', + '/base:0x10000', + + '/entry:DrvEnableDriver', + ]) + + + createConvenienceLibBuilder(env) + + # for debugging #print env.Dump() diff --git a/winddk.py b/winddk.py index c112329cd6..58de183857 100644 --- a/winddk.py +++ b/winddk.py @@ -89,105 +89,6 @@ def get_winddk_paths(env, version=None): exe_path = string.join(exe_paths, os.pathsep ) return (include_path, lib_path, exe_path) -def set_winddk_flags(env): - """Mimic WINDDK's builtin flags. - - See also: - - WINDDK's bin/makefile.new i386mk.inc for more info. - - buildchk_wxp_x86.log files, generated by the WINDDK's build - - http://alter.org.ua/docs/nt_kernel/vc8_proj/ - """ - - cppdefines = [ - ('_X86_', '1'), - ('i386', '1'), - 'STD_CALL', - ('CONDITION_HANDLING', '1'), - ('NT_INST', '0'), - ('WIN32', '100'), - ('_NT1X_', '100'), - ('WINNT', '1'), - ('_WIN32_WINNT', '0x0501'), # minimum required OS version - ('WINVER', '0x0501'), - ('_WIN32_IE', '0x0603'), - ('WIN32_LEAN_AND_MEAN', '1'), - ('DEVL', '1'), - ('__BUILDMACHINE__', 'WinDDK'), - ('FPO', '0'), - ] - if env.get('DEBUG', False): - cppdefines += [ - ('DBG', 1), - ] - env.Append(CPPDEFINES = cppdefines) - - # See also: - # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx - # - cl /? - cflags = [ - '/Zl', # omit default library name in .OBJ - '/Zp8', # 8bytes struct member alignment - '/Gy', # separate functions for linker - '/Gm-', # disable minimal rebuild - '/W3', # warning level - '/WX', # treat warnings as errors - '/Gz', # __stdcall Calling convention - '/GX-', # disable C++ EH - '/GR-', # disable C++ RTTI - '/GF', # enable read-only string pooling - '/GS', # enable security checks - '/G6', # optimize for PPro, P-II, P-III - '/Ze', # enable extensions - #'/Gi-', # ??? - '/QIfdiv-', # disable Pentium FDIV fix - #'/hotpatch', # ??? - #'/Z7', #enable old-style debug info - ] - if env.get('debug', False): - cflags += [ - '/Od', # disable optimizations - '/Oi', # enable intrinsic functions - '/Oy-', # disable frame pointer omission - ] - else: - cflags += [ - '/Ox', # maximum optimizations - '/Oi', # enable intrinsic functions - '/Os', # favor code space - ] - env.Append(CFLAGS = cflags) - env.Append(CXXFLAGS = cflags) - - # See also: - # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx - env.Append(LINKFLAGS = [ - '/merge:_PAGE=PAGE', - '/merge:_TEXT=.text', - '/section:INIT,d', - '/opt:ref', - '/opt:icf', - '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221', - '/incremental:no', - '/fullbuild', - '/release', - '/nodefaultlib', - '/wx', - '/debug', - '/debugtype:cv', - '/version:5.1', - '/osversion:5.1', - '/functionpadmin:5', - '/safeseh', - '/pdbcompress', - '/stack:0x40000,0x1000', - '/driver', - '/align:0x80', - '/subsystem:native,5.01', - '/base:0x10000', - - '/entry:DrvEnableDriver', - ]) - def validate_vars(env): """Validate the PCH and PCHSTOP construction variables.""" if env.has_key('PCH') and env['PCH']: @@ -314,8 +215,6 @@ def generate(env): SCons.Tool.mslink.generate(env) - set_winddk_flags(env) - if not env.has_key('ENV'): env['ENV'] = {} -- cgit v1.2.3 From a7ce6d399221fbb59d96d56c853de9781bbf2547 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 25 Apr 2008 19:53:13 +0900 Subject: scons: More windows userspace fixes. --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 9b46e6ade2..ea624b13a7 100644 --- a/SConstruct +++ b/SConstruct @@ -160,7 +160,7 @@ if llvm: env['LINK'] = env['CXX'] # libGL -if platform not in ('winddk',): +if platform in ('linux', 'freebsd', 'darwin'): env.Append(LIBS = [ 'X11', 'Xext', -- cgit v1.2.3 From 658f5e721316f1983ae39b6b94b992baca0e2bc2 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 26 Apr 2008 01:14:32 +0900 Subject: scons: A few fixes for building mesa on windows. --- SConstruct | 6 ------ src/mesa/SConscript | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index ea624b13a7..e7c10fcf52 100644 --- a/SConstruct +++ b/SConstruct @@ -108,12 +108,6 @@ env.Append(CPPPATH = [ # x86 assembly if x86: - env.Append(CPPDEFINES = [ - 'USE_X86_ASM', - 'USE_MMX_ASM', - 'USE_3DNOW_ASM', - 'USE_SSE_ASM', - ]) if gcc: env.Append(CFLAGS = '-m32') env.Append(CXXFLAGS = '-m32') diff --git a/src/mesa/SConscript b/src/mesa/SConscript index 80fbdb41f0..6b99dacf2a 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -12,9 +12,19 @@ env.Append(CPPPATH = [ '#/src/mesa/main', ]) -env.Append(CFLAGS = [ - '-std=c99', -]) +if gcc: + env.Append(CFLAGS = [ + '-std=c99', + ]) + +# x86 assembly +if x86 and gcc: + env.Append(CPPDEFINES = [ + 'USE_X86_ASM', + 'USE_MMX_ASM', + 'USE_3DNOW_ASM', + 'USE_SSE_ASM', + ]) ####################################################################### @@ -269,7 +279,7 @@ SPARC_API = [ 'sparc/glapi_sparc.S', ] -if x86: +if x86 and gcc: ASM_SOURCES = ASM_C_SOURCES + X86_SOURCES API_SOURCES = X86_API else: -- cgit v1.2.3 From b215d7d10c011adce839b80f87c0ea03a3edd427 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 28 May 2008 01:24:06 +0900 Subject: scons: Play nice with MS Embedded Visual C++. --- SConstruct | 5 +- common.py | 24 +++++- scons/evc.py | 108 ++++++++++++++++++++++++ scons/mslib_sa.py | 49 +++++++++++ scons/mslink_sa.py | 211 +++++++++++++++++++++++++++++++++++++++++++++++ scons/msvc_sa.py | 173 +++++++++++++++++++++++++++++++++++++++ scons/winddk.py | 114 ++++++++++++++++++++++++++ winddk.py | 236 ----------------------------------------------------- 8 files changed, 680 insertions(+), 240 deletions(-) create mode 100644 scons/evc.py create mode 100644 scons/mslib_sa.py create mode 100644 scons/mslink_sa.py create mode 100644 scons/msvc_sa.py create mode 100644 scons/winddk.py delete mode 100644 winddk.py (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index e7c10fcf52..5f7b6dd4d1 100644 --- a/SConstruct +++ b/SConstruct @@ -85,7 +85,7 @@ Export([ # TODO: auto-detect as much as possible if platform == 'winddk': - env.Tool('winddk', ['.']) + env.Tool('winddk', ['scons']) env.Append(CPPPATH = [ env['SDK_INC_PATH'], @@ -94,6 +94,9 @@ if platform == 'winddk': env['CRT_INC_PATH'], ]) +if platform == 'wince': + env.Tool('evc', ['scons']) + common.generate(env) diff --git a/common.py b/common.py index d3c0261d71..c040c6ddd4 100644 --- a/common.py +++ b/common.py @@ -34,7 +34,7 @@ default_machine = _machine_map.get(default_machine, 'generic') if default_platform in ('linux', 'freebsd', 'darwin'): default_dri = 'yes' -elif default_platform in ('winddk', 'windows'): +elif default_platform in ('winddk', 'windows', 'wince'): default_dri = 'no' else: default_dri = 'no' @@ -58,7 +58,7 @@ def AddOptions(opts): opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, allowed_values=('generic', 'x86', 'x86_64'))) opts.Add(EnumOption('platform', 'target platform', default_platform, - allowed_values=('linux', 'cell', 'windows', 'winddk'))) + allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince'))) opts.Add(BoolOption('llvm', 'use LLVM', 'no')) opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) @@ -149,7 +149,7 @@ def generate(env): platform = env['platform'] x86 = env['machine'] == 'x86' gcc = env['platform'] in ('linux', 'freebsd', 'darwin') - msvc = env['platform'] in ('windows', 'winddk') + msvc = env['platform'] in ('windows', 'winddk', 'wince') # C preprocessor options cppdefines = [] @@ -196,6 +196,19 @@ def generate(env): ] if debug: cppdefines += [('DBG', 1)] + if platform == 'wince': + cppdefines += [ + ('_WIN32_WCE', '500'), + 'WCE_PLATFORM_STANDARDSDK_500', + '_i386_', + ('UNDER_CE', '500'), + 'UNICODE', + '_UNICODE', + '_X86_', + 'x86', + '_USRDLL', + 'TEST_EXPORTS' , + ] if platform == 'windows': cppdefines += ['PIPE_SUBSYSTEM_USER'] if platform == 'winddk': @@ -264,6 +277,11 @@ def generate(env): '/hotpatch', # prepares an image for hotpatching. #'/Z7', #enable old-style debug info ] + if platform == 'wince': + cflags += [ + '/Gs8192', + '/GF', # enable read-only string pooling + ] # Put debugging information in a separate .pdb file for each object file as # descrived in the scons manpage env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' diff --git a/scons/evc.py b/scons/evc.py new file mode 100644 index 0000000000..22a92607e5 --- /dev/null +++ b/scons/evc.py @@ -0,0 +1,108 @@ +"""evc + +Tool-specific initialization for Microsoft eMbedded Visual C++. + +""" + +# +# Copyright (c) 2001-2007 The SCons Foundation +# Copyright (c) 2008 Tungsten Graphics, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import os.path +import re +import string + +import SCons.Action +import SCons.Builder +import SCons.Errors +import SCons.Platform.win32 +import SCons.Tool +import SCons.Util +import SCons.Warnings + +import msvc_sa +import mslib_sa +import mslink_sa + +def get_evc_paths(env, version=None): + """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values + of those three environment variables that should be set + in order to execute the MSVC tools properly.""" + + exe_paths = [] + lib_paths = [] + include_paths = [] + + # mymic the batch files located in Microsoft eMbedded C++ 4.0\EVC\WCExxx\BIN + os_version = os.environ.get('OSVERSION', 'WCE500') + platform = os.environ.get('PLATFORM', 'STANDARDSDK_500') + wce_root = os.environ.get('WCEROOT', 'C:\\Program Files\\Microsoft eMbedded C++ 4.0') + sdk_root = os.environ.get('SDKROOT', 'C:\\Windows CE Tools') + + target_cpu = 'x86' + cfg = 'none' + + exe_paths.append( os.path.join(wce_root, 'COMMON', 'EVC', 'bin') ) + exe_paths.append( os.path.join(wce_root, 'EVC', os_version, 'bin') ) + include_paths.append( os.path.join(sdk_root, os_version, platform, 'include', target_cpu) ) + include_paths.append( os.path.join(sdk_root, os_version, platform, 'MFC', 'include') ) + include_paths.append( os.path.join(sdk_root, os_version, platform, 'ATL', 'include') ) + lib_paths.append( os.path.join(sdk_root, os_version, platform, 'lib', target_cpu) ) + lib_paths.append( os.path.join(sdk_root, os_version, platform, 'MFC', 'lib', target_cpu) ) + lib_paths.append( os.path.join(sdk_root, os_version, platform, 'ATL', 'lib', target_cpu) ) + + include_path = string.join( include_paths, os.pathsep ) + lib_path = string.join(lib_paths, os.pathsep ) + exe_path = string.join(exe_paths, os.pathsep ) + return (include_path, lib_path, exe_path) + +def generate(env): + + msvc_sa.generate(env) + mslib_sa.generate(env) + mslink_sa.generate(env) + + if not env.has_key('ENV'): + env['ENV'] = {} + + try: + include_path, lib_path, exe_path = get_evc_paths(env) + + # since other tools can set these, we just make sure that the + # relevant stuff from WINDDK is in there somewhere. + env.PrependENVPath('INCLUDE', include_path) + env.PrependENVPath('LIB', lib_path) + env.PrependENVPath('PATH', exe_path) + except (SCons.Util.RegError, SCons.Errors.InternalError): + pass + +def exists(env): + if not msvc_sa.exits(env): + return 0 + if not mslib_sa.exits(env): + return 0 + if not mslink_sa.exits(env): + return 0 + return 1 + +# vim:set ts=4 sw=4 et: diff --git a/scons/mslib_sa.py b/scons/mslib_sa.py new file mode 100644 index 0000000000..da51c574b6 --- /dev/null +++ b/scons/mslib_sa.py @@ -0,0 +1,49 @@ +"""mslib_sa + +Tool-specific initialization for lib (MicroSoft library archiver). + +Based on SCons.Tool.mslib, without the MSVC detection. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import SCons.Defaults +import SCons.Tool +import SCons.Util + +def generate(env): + """Add Builders and construction variables for lib to an Environment.""" + SCons.Tool.createStaticLibBuilder(env) + + env['AR'] = 'lib' + env['ARFLAGS'] = SCons.Util.CLVar('/nologo') + env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}" + env['LIBPREFIX'] = '' + env['LIBSUFFIX'] = '.lib' + +def exists(env): + return env.Detect('lib') + +# vim:set ts=4 sw=4 et: diff --git a/scons/mslink_sa.py b/scons/mslink_sa.py new file mode 100644 index 0000000000..53331def1a --- /dev/null +++ b/scons/mslink_sa.py @@ -0,0 +1,211 @@ +"""mslink_sa + +Tool-specific initialization for the Microsoft linker. + +Based on SCons.Tool.mslink, without the MSVS detection. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import os.path + +import SCons.Action +import SCons.Defaults +import SCons.Errors +import SCons.Platform.win32 +import SCons.Tool +import SCons.Tool.msvc +import SCons.Util + +def pdbGenerator(env, target, source, for_signature): + try: + return ['/PDB:%s' % target[0].attributes.pdb, '/DEBUG'] + except (AttributeError, IndexError): + return None + +def windowsShlinkTargets(target, source, env, for_signature): + listCmd = [] + dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX') + if dll: listCmd.append("/out:%s"%dll.get_string(for_signature)) + + implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX') + if implib: listCmd.append("/implib:%s"%implib.get_string(for_signature)) + + return listCmd + +def windowsShlinkSources(target, source, env, for_signature): + listCmd = [] + + deffile = env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX") + for src in source: + if src == deffile: + # Treat this source as a .def file. + listCmd.append("/def:%s" % src.get_string(for_signature)) + else: + # Just treat it as a generic source file. + listCmd.append(src) + return listCmd + +def windowsLibEmitter(target, source, env): + SCons.Tool.msvc.validate_vars(env) + + extratargets = [] + extrasources = [] + + dll = env.FindIxes(target, "SHLIBPREFIX", "SHLIBSUFFIX") + no_import_lib = env.get('no_import_lib', 0) + + if not dll: + raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX") + + insert_def = env.subst("$WINDOWS_INSERT_DEF") + if not insert_def in ['', '0', 0] and \ + not env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"): + + # append a def file to the list of sources + extrasources.append( + env.ReplaceIxes(dll, + "SHLIBPREFIX", "SHLIBSUFFIX", + "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")) + + if env.has_key('PDB') and env['PDB']: + pdb = env.arg2nodes('$PDB', target=target, source=source)[0] + extratargets.append(pdb) + target[0].attributes.pdb = pdb + + if not no_import_lib and \ + not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"): + # Append an import library to the list of targets. + extratargets.append( + env.ReplaceIxes(dll, + "SHLIBPREFIX", "SHLIBSUFFIX", + "LIBPREFIX", "LIBSUFFIX")) + # and .exp file is created if there are exports from a DLL + extratargets.append( + env.ReplaceIxes(dll, + "SHLIBPREFIX", "SHLIBSUFFIX", + "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX")) + + return (target+extratargets, source+extrasources) + +def prog_emitter(target, source, env): + SCons.Tool.msvc.validate_vars(env) + + extratargets = [] + + exe = env.FindIxes(target, "PROGPREFIX", "PROGSUFFIX") + if not exe: + raise SCons.Errors.UserError, "An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX") + + if env.has_key('PDB') and env['PDB']: + pdb = env.arg2nodes('$PDB', target=target, source=source)[0] + extratargets.append(pdb) + target[0].attributes.pdb = pdb + + return (target+extratargets,source) + +def RegServerFunc(target, source, env): + if env.has_key('register') and env['register']: + ret = regServerAction([target[0]], [source[0]], env) + if ret: + raise SCons.Errors.UserError, "Unable to register %s" % target[0] + else: + print "Registered %s sucessfully" % target[0] + return ret + return 0 + +regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR") +regServerCheck = SCons.Action.Action(RegServerFunc, None) +shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}') +compositeLinkAction = shlibLinkAction + regServerCheck + +def generate(env): + """Add Builders and construction variables for ar to an Environment.""" + SCons.Tool.createSharedLibBuilder(env) + SCons.Tool.createProgBuilder(env) + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll') + env['_SHLINK_TARGETS'] = windowsShlinkTargets + env['_SHLINK_SOURCES'] = windowsShlinkSources + env['SHLINKCOM'] = compositeLinkAction + env.Append(SHLIBEMITTER = [windowsLibEmitter]) + env['LINK'] = 'link' + env['LINKFLAGS'] = SCons.Util.CLVar('/nologo') + env['_PDB'] = pdbGenerator + env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $SOURCES.windows")}' + env.Append(PROGEMITTER = [prog_emitter]) + env['LIBDIRPREFIX']='/LIBPATH:' + env['LIBDIRSUFFIX']='' + env['LIBLINKPREFIX']='' + env['LIBLINKSUFFIX']='$LIBSUFFIX' + + env['WIN32DEFPREFIX'] = '' + env['WIN32DEFSUFFIX'] = '.def' + env['WIN32_INSERT_DEF'] = 0 + env['WINDOWSDEFPREFIX'] = '${WIN32DEFPREFIX}' + env['WINDOWSDEFSUFFIX'] = '${WIN32DEFSUFFIX}' + env['WINDOWS_INSERT_DEF'] = '${WIN32_INSERT_DEF}' + + env['WIN32EXPPREFIX'] = '' + env['WIN32EXPSUFFIX'] = '.exp' + env['WINDOWSEXPPREFIX'] = '${WIN32EXPPREFIX}' + env['WINDOWSEXPSUFFIX'] = '${WIN32EXPSUFFIX}' + + env['WINDOWSSHLIBMANIFESTPREFIX'] = '' + env['WINDOWSSHLIBMANIFESTSUFFIX'] = '${SHLIBSUFFIX}.manifest' + env['WINDOWSPROGMANIFESTPREFIX'] = '' + env['WINDOWSPROGMANIFESTSUFFIX'] = '${PROGSUFFIX}.manifest' + + env['REGSVRACTION'] = regServerCheck + env['REGSVR'] = os.path.join(SCons.Platform.win32.get_system_root(),'System32','regsvr32') + env['REGSVRFLAGS'] = '/s ' + env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}' + + # For most platforms, a loadable module is the same as a shared + # library. Platforms which are different can override these, but + # setting them the same means that LoadableModule works everywhere. + SCons.Tool.createLoadableModuleBuilder(env) + env['LDMODULE'] = '$SHLINK' + env['LDMODULEPREFIX'] = '$SHLIBPREFIX' + env['LDMODULESUFFIX'] = '$SHLIBSUFFIX' + env['LDMODULEFLAGS'] = '$SHLINKFLAGS' + # We can't use '$SHLINKCOM' here because that will stringify the + # action list on expansion, and will then try to execute expanded + # strings, with the upshot that it would try to execute RegServerFunc + # as a command. + env['LDMODULECOM'] = compositeLinkAction + +def exists(env): + platform = env.get('PLATFORM', '') + if platform in ('win32', 'cygwin'): + # Only explicitly search for a 'link' executable on Windows + # systems. Some other systems (e.g. Ubuntu Linux) have an + # executable named 'link' and we don't want that to make SCons + # think Visual Studio is installed. + return env.Detect('link') + return None + +# vim:set ts=4 sw=4 et: diff --git a/scons/msvc_sa.py b/scons/msvc_sa.py new file mode 100644 index 0000000000..136d305265 --- /dev/null +++ b/scons/msvc_sa.py @@ -0,0 +1,173 @@ +"""msvc_sa + +Tool-specific initialization for Microsoft Visual C/C++. + +Based on SCons.Tool.msvc, without the MSVS detection. + +""" + +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import os.path +import re +import string + +import SCons.Action +import SCons.Builder +import SCons.Errors +import SCons.Platform.win32 +import SCons.Tool +import SCons.Util +import SCons.Warnings + +CSuffixes = ['.c', '.C'] +CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] + +def validate_vars(env): + """Validate the PCH and PCHSTOP construction variables.""" + if env.has_key('PCH') and env['PCH']: + if not env.has_key('PCHSTOP'): + raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined." + if not SCons.Util.is_String(env['PCHSTOP']): + raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP'] + +def pch_emitter(target, source, env): + """Adds the object file target.""" + + validate_vars(env) + + pch = None + obj = None + + for t in target: + if SCons.Util.splitext(str(t))[1] == '.pch': + pch = t + if SCons.Util.splitext(str(t))[1] == '.obj': + obj = t + + if not obj: + obj = SCons.Util.splitext(str(pch))[0]+'.obj' + + target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work + + return (target, source) + +def object_emitter(target, source, env, parent_emitter): + """Sets up the PCH dependencies for an object file.""" + + validate_vars(env) + + parent_emitter(target, source, env) + + if env.has_key('PCH') and env['PCH']: + env.Depends(target, env['PCH']) + + return (target, source) + +def static_object_emitter(target, source, env): + return object_emitter(target, source, env, + SCons.Defaults.StaticObjectEmitter) + +def shared_object_emitter(target, source, env): + return object_emitter(target, source, env, + SCons.Defaults.SharedObjectEmitter) + +pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR') +pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch', + emitter=pch_emitter, + source_scanner=SCons.Tool.SourceFileScanner) +res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') +res_builder = SCons.Builder.Builder(action=res_action, + src_suffix='.rc', + suffix='.res', + src_builder=[], + source_scanner=SCons.Tool.SourceFileScanner) +SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) + +def generate(env): + """Add Builders and construction variables for MSVC++ to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCAction) + static_obj.add_emitter(suffix, static_object_emitter) + shared_obj.add_emitter(suffix, shared_object_emitter) + + for suffix in CXXSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CXXAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) + static_obj.add_emitter(suffix, static_object_emitter) + shared_obj.add_emitter(suffix, shared_object_emitter) + + env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}']) + env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}']) + env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS' + env['CC'] = 'cl' + env['CCFLAGS'] = SCons.Util.CLVar('/nologo') + env['CFLAGS'] = SCons.Util.CLVar('') + env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS' + env['SHCC'] = '$CC' + env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') + env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') + env['SHCCCOM'] = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS' + env['CXX'] = '$CC' + env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)') + env['CXXCOM'] = '$CXX $CXXFLAGS $CCCOMFLAGS' + env['SHCXX'] = '$CXX' + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') + env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS' + env['CPPDEFPREFIX'] = '/D' + env['CPPDEFSUFFIX'] = '' + env['INCPREFIX'] = '/I' + env['INCSUFFIX'] = '' +# env.Append(OBJEMITTER = [static_object_emitter]) +# env.Append(SHOBJEMITTER = [shared_object_emitter]) + env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 + + env['RC'] = 'rc' + env['RCFLAGS'] = SCons.Util.CLVar('') + env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES' + env['BUILDERS']['RES'] = res_builder + env['OBJPREFIX'] = '' + env['OBJSUFFIX'] = '.obj' + env['SHOBJPREFIX'] = '$OBJPREFIX' + env['SHOBJSUFFIX'] = '$OBJSUFFIX' + + env['CFILESUFFIX'] = '.c' + env['CXXFILESUFFIX'] = '.cc' + + env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}']) + env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS' + env['BUILDERS']['PCH'] = pch_builder + + if not env.has_key('ENV'): + env['ENV'] = {} + if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders + env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root() + +def exists(env): + return env.Detect('cl') + +# vim:set ts=4 sw=4 et: diff --git a/scons/winddk.py b/scons/winddk.py new file mode 100644 index 0000000000..be81d12ea9 --- /dev/null +++ b/scons/winddk.py @@ -0,0 +1,114 @@ +"""winddk + +Tool-specific initialization for Microsoft Windows DDK. + +""" + +# +# Copyright (c) 2001-2007 The SCons Foundation +# Copyright (c) 2008 Tungsten Graphics, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import os.path +import re +import string + +import SCons.Action +import SCons.Builder +import SCons.Errors +import SCons.Platform.win32 +import SCons.Tool +import SCons.Util +import SCons.Warnings + +import msvc_sa +import mslib_sa +import mslink_sa + +def get_winddk_paths(env, version=None): + """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values + of those three environment variables that should be set + in order to execute the MSVC tools properly.""" + + WINDDKdir = None + exe_paths = [] + lib_paths = [] + include_paths = [] + + if 'BASEDIR' in os.environ: + WINDDKdir = os.environ['BASEDIR'] + else: + WINDDKdir = "C:\\WINDDK\\3790.1830" + + exe_paths.append( os.path.join(WINDDKdir, 'bin') ) + exe_paths.append( os.path.join(WINDDKdir, 'bin', 'x86') ) + include_paths.append( os.path.join(WINDDKdir, 'inc', 'wxp') ) + lib_paths.append( os.path.join(WINDDKdir, 'lib') ) + + target_os = 'wxp' + target_cpu = 'i386' + + env['SDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', target_os) + env['CRT_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'crt') + env['DDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', target_os) + env['WDM_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', 'wdm', target_os) + + env['SDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) + env['CRT_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', 'crt', target_cpu) + env['DDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) + env['WDM_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) + + include_path = string.join( include_paths, os.pathsep ) + lib_path = string.join(lib_paths, os.pathsep ) + exe_path = string.join(exe_paths, os.pathsep ) + return (include_path, lib_path, exe_path) + +def generate(env): + + msvc_sa.generate(env) + mslib_sa.generate(env) + mslink_sa.generate(env) + + if not env.has_key('ENV'): + env['ENV'] = {} + + try: + include_path, lib_path, exe_path = get_winddk_paths(env) + + # since other tools can set these, we just make sure that the + # relevant stuff from WINDDK is in there somewhere. + env.PrependENVPath('INCLUDE', include_path) + env.PrependENVPath('LIB', lib_path) + env.PrependENVPath('PATH', exe_path) + except (SCons.Util.RegError, SCons.Errors.InternalError): + pass + +def exists(env): + if not msvc_sa.exits(env): + return 0 + if not mslib_sa.exits(env): + return 0 + if not mslink_sa.exits(env): + return 0 + return 1 + +# vim:set ts=4 sw=4 et: diff --git a/winddk.py b/winddk.py deleted file mode 100644 index 58de183857..0000000000 --- a/winddk.py +++ /dev/null @@ -1,236 +0,0 @@ -"""winddk - -Tool-specific initialization for Microsoft Windows DDK. - -Based on engine.SCons.Tool.msvc. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - -# -# Copyright (c) 2001-2007 The SCons Foundation -# Copyright (c) 2008 Tungsten Graphics, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -import os.path -import re -import string - -import SCons.Action -import SCons.Builder -import SCons.Errors -import SCons.Platform.win32 -import SCons.Tool -import SCons.Tool.mslib -import SCons.Tool.mslink -import SCons.Util -import SCons.Warnings - -CSuffixes = ['.c', '.C'] -CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] - -def get_winddk_paths(env, version=None): - """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values - of those three environment variables that should be set - in order to execute the MSVC tools properly.""" - - WINDDKdir = None - exe_paths = [] - lib_paths = [] - include_paths = [] - - if 'BASEDIR' in os.environ: - WINDDKdir = os.environ['BASEDIR'] - else: - WINDDKdir = "C:\\WINDDK\\3790.1830" - - exe_paths.append( os.path.join(WINDDKdir, 'bin') ) - exe_paths.append( os.path.join(WINDDKdir, 'bin', 'x86') ) - include_paths.append( os.path.join(WINDDKdir, 'inc', 'wxp') ) - lib_paths.append( os.path.join(WINDDKdir, 'lib') ) - - target_os = 'wxp' - target_cpu = 'i386' - - env['SDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', target_os) - env['CRT_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'crt') - env['DDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', target_os) - env['WDM_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', 'wdm', target_os) - - env['SDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) - env['CRT_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', 'crt', target_cpu) - env['DDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) - env['WDM_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu) - - include_path = string.join( include_paths, os.pathsep ) - lib_path = string.join(lib_paths, os.pathsep ) - exe_path = string.join(exe_paths, os.pathsep ) - return (include_path, lib_path, exe_path) - -def validate_vars(env): - """Validate the PCH and PCHSTOP construction variables.""" - if env.has_key('PCH') and env['PCH']: - if not env.has_key('PCHSTOP'): - raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined." - if not SCons.Util.is_String(env['PCHSTOP']): - raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP'] - -def pch_emitter(target, source, env): - """Adds the object file target.""" - - validate_vars(env) - - pch = None - obj = None - - for t in target: - if SCons.Util.splitext(str(t))[1] == '.pch': - pch = t - if SCons.Util.splitext(str(t))[1] == '.obj': - obj = t - - if not obj: - obj = SCons.Util.splitext(str(pch))[0]+'.obj' - - target = [pch, obj] # pch must be first, and obj second for the PCHCOM to work - - return (target, source) - -def object_emitter(target, source, env, parent_emitter): - """Sets up the PCH dependencies for an object file.""" - - validate_vars(env) - - parent_emitter(target, source, env) - - if env.has_key('PCH') and env['PCH']: - env.Depends(target, env['PCH']) - - return (target, source) - -def static_object_emitter(target, source, env): - return object_emitter(target, source, env, - SCons.Defaults.StaticObjectEmitter) - -def shared_object_emitter(target, source, env): - return object_emitter(target, source, env, - SCons.Defaults.SharedObjectEmitter) - -pch_action = SCons.Action.Action('$PCHCOM', '$PCHCOMSTR') -pch_builder = SCons.Builder.Builder(action=pch_action, suffix='.pch', - emitter=pch_emitter, - source_scanner=SCons.Tool.SourceFileScanner) -res_action = SCons.Action.Action('$RCCOM', '$RCCOMSTR') -res_builder = SCons.Builder.Builder(action=res_action, - src_suffix='.rc', - suffix='.res', - src_builder=[], - source_scanner=SCons.Tool.SourceFileScanner) -SCons.Tool.SourceFileScanner.add_scanner('.rc', SCons.Defaults.CScan) - -def generate(env): - """Add Builders and construction variables for MSVC++ to an Environment.""" - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - - for suffix in CSuffixes: - static_obj.add_action(suffix, SCons.Defaults.CAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCAction) - static_obj.add_emitter(suffix, static_object_emitter) - shared_obj.add_emitter(suffix, shared_object_emitter) - - for suffix in CXXSuffixes: - static_obj.add_action(suffix, SCons.Defaults.CXXAction) - shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) - static_obj.add_emitter(suffix, static_object_emitter) - shared_obj.add_emitter(suffix, shared_object_emitter) - - env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}']) - env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}']) - env['CCCOMFLAGS'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET $CCPCHFLAGS $CCPDBFLAGS' - env['CC'] = 'cl' - env['CCFLAGS'] = SCons.Util.CLVar('/nologo') - env['CFLAGS'] = SCons.Util.CLVar('') - env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $CCCOMFLAGS' - env['SHCC'] = '$CC' - env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') - env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS') - env['SHCCCOM'] = '$SHCC $SHCFLAGS $SHCCFLAGS $CCCOMFLAGS' - env['CXX'] = '$CC' - env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS $( /TP $)') - env['CXXCOM'] = '$CXX $CXXFLAGS $CCCOMFLAGS' - env['SHCXX'] = '$CXX' - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS') - env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CCCOMFLAGS' - env['CPPDEFPREFIX'] = '/D' - env['CPPDEFSUFFIX'] = '' - env['INCPREFIX'] = '/I' - env['INCSUFFIX'] = '' -# env.Append(OBJEMITTER = [static_object_emitter]) -# env.Append(SHOBJEMITTER = [shared_object_emitter]) - env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1 - - env['RC'] = 'rc' - env['RCFLAGS'] = SCons.Util.CLVar('') - env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES' - env['BUILDERS']['RES'] = res_builder - env['OBJPREFIX'] = '' - env['OBJSUFFIX'] = '.obj' - env['SHOBJPREFIX'] = '$OBJPREFIX' - env['SHOBJSUFFIX'] = '$OBJSUFFIX' - - env['CFILESUFFIX'] = '.c' - env['CXXFILESUFFIX'] = '.cc' - - env['PCHPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Yd") or ""}']) - env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS' - env['BUILDERS']['PCH'] = pch_builder - - env['AR'] = 'lib' - env['ARFLAGS'] = SCons.Util.CLVar('/nologo') - env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}" - env['LIBPREFIX'] = '' - env['LIBSUFFIX'] = '.lib' - - SCons.Tool.mslink.generate(env) - - if not env.has_key('ENV'): - env['ENV'] = {} - - try: - include_path, lib_path, exe_path = get_winddk_paths(env) - - # since other tools can set these, we just make sure that the - # relevant stuff from WINDDK is in there somewhere. - env.PrependENVPath('INCLUDE', include_path) - env.PrependENVPath('LIB', lib_path) - env.PrependENVPath('PATH', exe_path) - except (SCons.Util.RegError, SCons.Errors.InternalError): - pass - - -def exists(env): - return env.Detect('cl') - -# vim:set sw=4 et: -- cgit v1.2.3 From ffc6afcdbf14b5d26bd3665a269fdd28d944afed Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 31 May 2008 18:55:25 +0900 Subject: scons: Enable mesa state tracker in all platforms by default. But only actually build it on some. This results in a better default scons experience. --- SConstruct | 5 +- src/mesa/SConscript | 604 ++++++++++++++++++++++++++-------------------------- 2 files changed, 306 insertions(+), 303 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 5f7b6dd4d1..9c37b24f72 100644 --- a/SConstruct +++ b/SConstruct @@ -30,14 +30,15 @@ import common # Configuration options if common.default_platform in ('linux', 'freebsd', 'darwin'): - default_statetrackers = 'mesa' + default_statetrackers = 'all' default_drivers = 'softpipe,failover,i915simple,i965simple' default_winsys = 'xlib' elif common.default_platform in ('winddk',): - default_statetrackers = 'none' + default_statetrackers = 'all' default_drivers = 'softpipe,i915simple' default_winsys = 'none' else: + default_statetrackers = 'all' default_drivers = 'all' default_winsys = 'all' diff --git a/src/mesa/SConscript b/src/mesa/SConscript index 6b99dacf2a..04b771a7e1 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -4,307 +4,309 @@ Import('*') -env = env.Clone() +if env['platform'] != 'winddk': -# Includes -env.Append(CPPPATH = [ - '#/src/mesa', - '#/src/mesa/main', -]) - -if gcc: - env.Append(CFLAGS = [ - '-std=c99', - ]) - -# x86 assembly -if x86 and gcc: - env.Append(CPPDEFINES = [ - 'USE_X86_ASM', - 'USE_MMX_ASM', - 'USE_3DNOW_ASM', - 'USE_SSE_ASM', + env = env.Clone() + + # Includes + env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', ]) - - -####################################################################### -# Core sources - -MAIN_SOURCES = [ - 'main/api_arrayelt.c', - 'main/api_loopback.c', - 'main/api_noop.c', - 'main/api_validate.c', - 'main/accum.c', - 'main/attrib.c', - 'main/arrayobj.c', - 'main/blend.c', - 'main/bufferobj.c', - 'main/buffers.c', - 'main/clip.c', - 'main/colortab.c', - 'main/context.c', - 'main/convolve.c', - 'main/debug.c', - 'main/depth.c', - 'main/depthstencil.c', - 'main/dlist.c', - 'main/drawpix.c', - 'main/enable.c', - 'main/enums.c', - 'main/eval.c', - 'main/execmem.c', - 'main/extensions.c', - 'main/fbobject.c', - 'main/feedback.c', - 'main/ffvertex_prog.c', - 'main/fog.c', - 'main/framebuffer.c', - 'main/get.c', - 'main/getstring.c', - 'main/hash.c', - 'main/hint.c', - 'main/histogram.c', - 'main/image.c', - 'main/imports.c', - 'main/light.c', - 'main/lines.c', - 'main/matrix.c', - 'main/mipmap.c', - 'main/mm.c', - 'main/pixel.c', - 'main/points.c', - 'main/polygon.c', - 'main/queryobj.c', - 'main/rastpos.c', - 'main/rbadaptors.c', - 'main/renderbuffer.c', - 'main/shaders.c', - 'main/state.c', - 'main/stencil.c', - 'main/texcompress.c', - 'main/texcompress_s3tc.c', - 'main/texcompress_fxt1.c', - 'main/texenvprogram.c', - 'main/texformat.c', - 'main/teximage.c', - 'main/texobj.c', - 'main/texrender.c', - 'main/texstate.c', - 'main/texstore.c', - 'main/varray.c', - 'main/vtxfmt.c', -] - -GLAPI_SOURCES = [ - 'main/dispatch.c', - 'glapi/glapi.c', - 'glapi/glthread.c', -] - -MATH_SOURCES = [ - 'math/m_debug_clip.c', - 'math/m_debug_norm.c', - 'math/m_debug_xform.c', - 'math/m_eval.c', - 'math/m_matrix.c', - 'math/m_translate.c', - 'math/m_vector.c', - 'math/m_xform.c', -] - -VBO_SOURCES = [ - 'vbo/vbo_context.c', - 'vbo/vbo_exec.c', - 'vbo/vbo_exec_api.c', - 'vbo/vbo_exec_array.c', - 'vbo/vbo_exec_draw.c', - 'vbo/vbo_exec_eval.c', - 'vbo/vbo_rebase.c', - 'vbo/vbo_split.c', - 'vbo/vbo_split_copy.c', - 'vbo/vbo_split_inplace.c', - 'vbo/vbo_save.c', - 'vbo/vbo_save_api.c', - 'vbo/vbo_save_draw.c', - 'vbo/vbo_save_loopback.c', -] - -VF_SOURCES = [ - 'vf/vf.c', - 'vf/vf_generic.c', - 'vf/vf_sse.c', -] - -STATETRACKER_SOURCES = [ - 'state_tracker/st_atom.c', - 'state_tracker/st_atom_blend.c', - 'state_tracker/st_atom_clip.c', - 'state_tracker/st_atom_constbuf.c', - 'state_tracker/st_atom_depth.c', - 'state_tracker/st_atom_framebuffer.c', - 'state_tracker/st_atom_pixeltransfer.c', - 'state_tracker/st_atom_sampler.c', - 'state_tracker/st_atom_scissor.c', - 'state_tracker/st_atom_shader.c', - 'state_tracker/st_atom_rasterizer.c', - 'state_tracker/st_atom_stipple.c', - 'state_tracker/st_atom_texture.c', - 'state_tracker/st_atom_viewport.c', - 'state_tracker/st_cb_accum.c', - 'state_tracker/st_cb_bitmap.c', - 'state_tracker/st_cb_blit.c', - 'state_tracker/st_cb_bufferobjects.c', - 'state_tracker/st_cb_clear.c', - 'state_tracker/st_cb_flush.c', - 'state_tracker/st_cb_drawpixels.c', - 'state_tracker/st_cb_fbo.c', - 'state_tracker/st_cb_feedback.c', - 'state_tracker/st_cb_program.c', - 'state_tracker/st_cb_queryobj.c', - 'state_tracker/st_cb_rasterpos.c', - 'state_tracker/st_cb_readpixels.c', - 'state_tracker/st_cb_strings.c', - 'state_tracker/st_cb_texture.c', - 'state_tracker/st_context.c', - 'state_tracker/st_debug.c', - 'state_tracker/st_draw.c', - 'state_tracker/st_extensions.c', - 'state_tracker/st_format.c', - 'state_tracker/st_framebuffer.c', - 'state_tracker/st_gen_mipmap.c', - 'state_tracker/st_mesa_to_tgsi.c', - 'state_tracker/st_program.c', - 'state_tracker/st_texture.c', -] - -SHADER_SOURCES = [ - 'shader/arbprogparse.c', - 'shader/arbprogram.c', - 'shader/atifragshader.c', - 'shader/grammar/grammar_mesa.c', - 'shader/nvfragparse.c', - 'shader/nvprogram.c', - 'shader/nvvertparse.c', - 'shader/program.c', - 'shader/prog_cache.c', - 'shader/prog_debug.c', - 'shader/prog_execute.c', - 'shader/prog_instruction.c', - 'shader/prog_parameter.c', - 'shader/prog_print.c', - 'shader/prog_statevars.c', - 'shader/prog_uniform.c', - 'shader/programopt.c', - 'shader/shader_api.c', -] - -SLANG_SOURCES = [ - 'shader/slang/slang_builtin.c', - 'shader/slang/slang_codegen.c', - 'shader/slang/slang_compile.c', - 'shader/slang/slang_compile_function.c', - 'shader/slang/slang_compile_operation.c', - 'shader/slang/slang_compile_struct.c', - 'shader/slang/slang_compile_variable.c', - 'shader/slang/slang_emit.c', - 'shader/slang/slang_ir.c', - 'shader/slang/slang_label.c', - 'shader/slang/slang_library_noise.c', - 'shader/slang/slang_link.c', - 'shader/slang/slang_log.c', - 'shader/slang/slang_mem.c', - 'shader/slang/slang_preprocess.c', - 'shader/slang/slang_print.c', - 'shader/slang/slang_simplify.c', - 'shader/slang/slang_storage.c', - 'shader/slang/slang_typeinfo.c', - 'shader/slang/slang_vartable.c', - 'shader/slang/slang_utility.c', -] - - -####################################################################### -# Assembly sources - -ASM_C_SOURCES = [ - 'x86/common_x86.c', - 'x86/x86.c', - 'x86/3dnow.c', - 'x86/sse.c', - 'sparc/sparc.c', - 'ppc/common_ppc.c', - 'x86-64/x86-64.c', -] - -X86_SOURCES = [ - 'x86/common_x86_asm.S', - 'x86/x86_xform2.S', - 'x86/x86_xform3.S', - 'x86/x86_xform4.S', - 'x86/x86_cliptest.S', - 'x86/mmx_blend.S', - 'x86/3dnow_xform1.S', - 'x86/3dnow_xform2.S', - 'x86/3dnow_xform3.S', - 'x86/3dnow_xform4.S', - 'x86/3dnow_normal.S', - 'x86/sse_xform1.S', - 'x86/sse_xform2.S', - 'x86/sse_xform3.S', - 'x86/sse_xform4.S', - 'x86/sse_normal.S', - 'x86/read_rgba_span_x86.S', -] - -X86_API = [ - 'x86/glapi_x86.S', -] - -X86_64_SOURCES = [ - 'x86-64/xform4.S', -] - -X86_64_API = [ - 'x86-64/glapi_x86-64.S', -] - -SPARC_SOURCES = [ - 'sparc/clip.S', - 'sparc/norm.S', - 'sparc/xform.S', -] - -SPARC_API = [ - 'sparc/glapi_sparc.S', -] - -if x86 and gcc: - ASM_SOURCES = ASM_C_SOURCES + X86_SOURCES - API_SOURCES = X86_API -else: - ASM_SOURCES = [] - API_SOURCES = [] - -SOLO_SOURCES = \ - MAIN_SOURCES + \ - MATH_SOURCES + \ - VBO_SOURCES + \ - VF_SOURCES + \ - STATETRACKER_SOURCES + \ - SHADER_SOURCES + \ - ASM_SOURCES + \ - SLANG_SOURCES - -mesa = env.ConvenienceLibrary( - target = 'mesa', - source = SOLO_SOURCES, -) -Export('mesa') - -if not dri: - glapi = env.ConvenienceLibrary( - target = 'glapi', - source = GLAPI_SOURCES + API_SOURCES, + + if gcc: + env.Append(CFLAGS = [ + '-std=c99', + ]) + + # x86 assembly + if x86 and gcc: + env.Append(CPPDEFINES = [ + 'USE_X86_ASM', + 'USE_MMX_ASM', + 'USE_3DNOW_ASM', + 'USE_SSE_ASM', + ]) + + + ####################################################################### + # Core sources + + MAIN_SOURCES = [ + 'main/api_arrayelt.c', + 'main/api_loopback.c', + 'main/api_noop.c', + 'main/api_validate.c', + 'main/accum.c', + 'main/attrib.c', + 'main/arrayobj.c', + 'main/blend.c', + 'main/bufferobj.c', + 'main/buffers.c', + 'main/clip.c', + 'main/colortab.c', + 'main/context.c', + 'main/convolve.c', + 'main/debug.c', + 'main/depth.c', + 'main/depthstencil.c', + 'main/dlist.c', + 'main/drawpix.c', + 'main/enable.c', + 'main/enums.c', + 'main/eval.c', + 'main/execmem.c', + 'main/extensions.c', + 'main/fbobject.c', + 'main/feedback.c', + 'main/ffvertex_prog.c', + 'main/fog.c', + 'main/framebuffer.c', + 'main/get.c', + 'main/getstring.c', + 'main/hash.c', + 'main/hint.c', + 'main/histogram.c', + 'main/image.c', + 'main/imports.c', + 'main/light.c', + 'main/lines.c', + 'main/matrix.c', + 'main/mipmap.c', + 'main/mm.c', + 'main/pixel.c', + 'main/points.c', + 'main/polygon.c', + 'main/queryobj.c', + 'main/rastpos.c', + 'main/rbadaptors.c', + 'main/renderbuffer.c', + 'main/shaders.c', + 'main/state.c', + 'main/stencil.c', + 'main/texcompress.c', + 'main/texcompress_s3tc.c', + 'main/texcompress_fxt1.c', + 'main/texenvprogram.c', + 'main/texformat.c', + 'main/teximage.c', + 'main/texobj.c', + 'main/texrender.c', + 'main/texstate.c', + 'main/texstore.c', + 'main/varray.c', + 'main/vtxfmt.c', + ] + + GLAPI_SOURCES = [ + 'main/dispatch.c', + 'glapi/glapi.c', + 'glapi/glthread.c', + ] + + MATH_SOURCES = [ + 'math/m_debug_clip.c', + 'math/m_debug_norm.c', + 'math/m_debug_xform.c', + 'math/m_eval.c', + 'math/m_matrix.c', + 'math/m_translate.c', + 'math/m_vector.c', + 'math/m_xform.c', + ] + + VBO_SOURCES = [ + 'vbo/vbo_context.c', + 'vbo/vbo_exec.c', + 'vbo/vbo_exec_api.c', + 'vbo/vbo_exec_array.c', + 'vbo/vbo_exec_draw.c', + 'vbo/vbo_exec_eval.c', + 'vbo/vbo_rebase.c', + 'vbo/vbo_split.c', + 'vbo/vbo_split_copy.c', + 'vbo/vbo_split_inplace.c', + 'vbo/vbo_save.c', + 'vbo/vbo_save_api.c', + 'vbo/vbo_save_draw.c', + 'vbo/vbo_save_loopback.c', + ] + + VF_SOURCES = [ + 'vf/vf.c', + 'vf/vf_generic.c', + 'vf/vf_sse.c', + ] + + STATETRACKER_SOURCES = [ + 'state_tracker/st_atom.c', + 'state_tracker/st_atom_blend.c', + 'state_tracker/st_atom_clip.c', + 'state_tracker/st_atom_constbuf.c', + 'state_tracker/st_atom_depth.c', + 'state_tracker/st_atom_framebuffer.c', + 'state_tracker/st_atom_pixeltransfer.c', + 'state_tracker/st_atom_sampler.c', + 'state_tracker/st_atom_scissor.c', + 'state_tracker/st_atom_shader.c', + 'state_tracker/st_atom_rasterizer.c', + 'state_tracker/st_atom_stipple.c', + 'state_tracker/st_atom_texture.c', + 'state_tracker/st_atom_viewport.c', + 'state_tracker/st_cb_accum.c', + 'state_tracker/st_cb_bitmap.c', + 'state_tracker/st_cb_blit.c', + 'state_tracker/st_cb_bufferobjects.c', + 'state_tracker/st_cb_clear.c', + 'state_tracker/st_cb_flush.c', + 'state_tracker/st_cb_drawpixels.c', + 'state_tracker/st_cb_fbo.c', + 'state_tracker/st_cb_feedback.c', + 'state_tracker/st_cb_program.c', + 'state_tracker/st_cb_queryobj.c', + 'state_tracker/st_cb_rasterpos.c', + 'state_tracker/st_cb_readpixels.c', + 'state_tracker/st_cb_strings.c', + 'state_tracker/st_cb_texture.c', + 'state_tracker/st_context.c', + 'state_tracker/st_debug.c', + 'state_tracker/st_draw.c', + 'state_tracker/st_extensions.c', + 'state_tracker/st_format.c', + 'state_tracker/st_framebuffer.c', + 'state_tracker/st_gen_mipmap.c', + 'state_tracker/st_mesa_to_tgsi.c', + 'state_tracker/st_program.c', + 'state_tracker/st_texture.c', + ] + + SHADER_SOURCES = [ + 'shader/arbprogparse.c', + 'shader/arbprogram.c', + 'shader/atifragshader.c', + 'shader/grammar/grammar_mesa.c', + 'shader/nvfragparse.c', + 'shader/nvprogram.c', + 'shader/nvvertparse.c', + 'shader/program.c', + 'shader/prog_cache.c', + 'shader/prog_debug.c', + 'shader/prog_execute.c', + 'shader/prog_instruction.c', + 'shader/prog_parameter.c', + 'shader/prog_print.c', + 'shader/prog_statevars.c', + 'shader/prog_uniform.c', + 'shader/programopt.c', + 'shader/shader_api.c', + ] + + SLANG_SOURCES = [ + 'shader/slang/slang_builtin.c', + 'shader/slang/slang_codegen.c', + 'shader/slang/slang_compile.c', + 'shader/slang/slang_compile_function.c', + 'shader/slang/slang_compile_operation.c', + 'shader/slang/slang_compile_struct.c', + 'shader/slang/slang_compile_variable.c', + 'shader/slang/slang_emit.c', + 'shader/slang/slang_ir.c', + 'shader/slang/slang_label.c', + 'shader/slang/slang_library_noise.c', + 'shader/slang/slang_link.c', + 'shader/slang/slang_log.c', + 'shader/slang/slang_mem.c', + 'shader/slang/slang_preprocess.c', + 'shader/slang/slang_print.c', + 'shader/slang/slang_simplify.c', + 'shader/slang/slang_storage.c', + 'shader/slang/slang_typeinfo.c', + 'shader/slang/slang_vartable.c', + 'shader/slang/slang_utility.c', + ] + + + ####################################################################### + # Assembly sources + + ASM_C_SOURCES = [ + 'x86/common_x86.c', + 'x86/x86.c', + 'x86/3dnow.c', + 'x86/sse.c', + 'sparc/sparc.c', + 'ppc/common_ppc.c', + 'x86-64/x86-64.c', + ] + + X86_SOURCES = [ + 'x86/common_x86_asm.S', + 'x86/x86_xform2.S', + 'x86/x86_xform3.S', + 'x86/x86_xform4.S', + 'x86/x86_cliptest.S', + 'x86/mmx_blend.S', + 'x86/3dnow_xform1.S', + 'x86/3dnow_xform2.S', + 'x86/3dnow_xform3.S', + 'x86/3dnow_xform4.S', + 'x86/3dnow_normal.S', + 'x86/sse_xform1.S', + 'x86/sse_xform2.S', + 'x86/sse_xform3.S', + 'x86/sse_xform4.S', + 'x86/sse_normal.S', + 'x86/read_rgba_span_x86.S', + ] + + X86_API = [ + 'x86/glapi_x86.S', + ] + + X86_64_SOURCES = [ + 'x86-64/xform4.S', + ] + + X86_64_API = [ + 'x86-64/glapi_x86-64.S', + ] + + SPARC_SOURCES = [ + 'sparc/clip.S', + 'sparc/norm.S', + 'sparc/xform.S', + ] + + SPARC_API = [ + 'sparc/glapi_sparc.S', + ] + + if x86 and gcc: + ASM_SOURCES = ASM_C_SOURCES + X86_SOURCES + API_SOURCES = X86_API + else: + ASM_SOURCES = [] + API_SOURCES = [] + + SOLO_SOURCES = \ + MAIN_SOURCES + \ + MATH_SOURCES + \ + VBO_SOURCES + \ + VF_SOURCES + \ + STATETRACKER_SOURCES + \ + SHADER_SOURCES + \ + ASM_SOURCES + \ + SLANG_SOURCES + + mesa = env.ConvenienceLibrary( + target = 'mesa', + source = SOLO_SOURCES, ) - Export('glapi') + Export('mesa') + + if not dri: + glapi = env.ConvenienceLibrary( + target = 'glapi', + source = GLAPI_SOURCES + API_SOURCES, + ) + Export('glapi') -- cgit v1.2.3 From 5a67df6d7cc8c74bfb71a8f19b8f6fdfb525091b Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 3 Jun 2008 00:04:19 +0900 Subject: scons: Integrate gdi winsys. Conditional build of the winsys based on the platform. --- SConstruct | 4 +- src/gallium/winsys/SConscript | 9 ++- src/gallium/winsys/dri/SConscript | 101 ++++++++++++++++---------------- src/gallium/winsys/dri/intel/SConscript | 76 ++++++++++++------------ src/gallium/winsys/xlib/SConscript | 50 ++++++++-------- 5 files changed, 126 insertions(+), 114 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 9c37b24f72..549ff647ea 100644 --- a/SConstruct +++ b/SConstruct @@ -36,7 +36,7 @@ if common.default_platform in ('linux', 'freebsd', 'darwin'): elif common.default_platform in ('winddk',): default_statetrackers = 'all' default_drivers = 'softpipe,i915simple' - default_winsys = 'none' + default_winsys = 'all' else: default_statetrackers = 'all' default_drivers = 'all' @@ -49,7 +49,7 @@ opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetra opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell'])) opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, - ['xlib', 'intel'])) + ['xlib', 'intel', 'gdi'])) env = Environment( options = opts, diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index e8a581adb2..bf1718e7a5 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,11 +1,16 @@ Import('*') -if 'intel' in env['winsys'] and dri: +if env['dri']: SConscript([ 'dri/SConscript', ]) -if 'xlib' in env['winsys'] and not dri: +if 'xlib' in env['winsys']: SConscript([ 'xlib/SConscript', ]) + +if 'gdi' in env['winsys']: + SConscript([ + 'gdi/SConscript', + ]) diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript index 8c56ce917c..aef5210a32 100644 --- a/src/gallium/winsys/dri/SConscript +++ b/src/gallium/winsys/dri/SConscript @@ -1,51 +1,54 @@ Import('*') -drienv = env.Clone() - -drienv.Replace(CPPPATH = [ - '#src/mesa/drivers/dri/common', - '#include', - '#include/GL/internal', - '#src/gallium/include', - '#src/gallium/auxiliary', - '#src/gallium/drivers', - '#src/mesa', - '#src/mesa/main', - '#src/mesa/glapi', - '#src/mesa/math', - '#src/mesa/transform', - '#src/mesa/shader', - '#src/mesa/swrast', - '#src/mesa/swrast_setup', - '#src/egl/main', - '#src/egl/drivers/dri', -]) - -drienv.ParseConfig('pkg-config --cflags --libs libdrm') - -COMMON_GALLIUM_SOURCES = [ - '#src/mesa/drivers/dri/common/utils.c', - '#src/mesa/drivers/dri/common/vblank.c', - '#src/mesa/drivers/dri/common/dri_util.c', - '#src/mesa/drivers/dri/common/xmlconfig.c', -] - -COMMON_BM_SOURCES = [ - '#src/mesa/drivers/dri/common/dri_bufmgr.c', - '#src/mesa/drivers/dri/common/dri_drmpool.c', -] - -Export([ - 'drienv', - 'COMMON_GALLIUM_SOURCES', - 'COMMON_BM_SOURCES', -]) - -# TODO: Installation -#install: $(LIBNAME) -# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) -# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) - -SConscript([ - 'intel/SConscript', -]) +if env['dri']: + + drienv = env.Clone() + + drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', + ]) + + drienv.ParseConfig('pkg-config --cflags --libs libdrm') + + COMMON_GALLIUM_SOURCES = [ + '#src/mesa/drivers/dri/common/utils.c', + '#src/mesa/drivers/dri/common/vblank.c', + '#src/mesa/drivers/dri/common/dri_util.c', + '#src/mesa/drivers/dri/common/xmlconfig.c', + ] + + COMMON_BM_SOURCES = [ + '#src/mesa/drivers/dri/common/dri_bufmgr.c', + '#src/mesa/drivers/dri/common/dri_drmpool.c', + ] + + Export([ + 'drienv', + 'COMMON_GALLIUM_SOURCES', + 'COMMON_BM_SOURCES', + ]) + + # TODO: Installation + #install: $(LIBNAME) + # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) + # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + + if 'intel' in env['winsys']: + SConscript([ + 'intel/SConscript', + ]) diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript index 0ad19d42a8..6a4f50afcc 100644 --- a/src/gallium/winsys/dri/intel/SConscript +++ b/src/gallium/winsys/dri/intel/SConscript @@ -1,39 +1,41 @@ Import('*') -env = drienv.Clone() - -env.Append(CPPPATH = [ - '../intel', - 'server' -]) - -#MINIGLX_SOURCES = server/intel_dri.c - -DRIVER_SOURCES = [ - 'intel_winsys_pipe.c', - 'intel_winsys_softpipe.c', - 'intel_winsys_i915.c', - 'intel_batchbuffer.c', - 'intel_swapbuffers.c', - 'intel_context.c', - 'intel_lock.c', - 'intel_screen.c', - 'intel_batchpool.c', -] - -sources = \ - COMMON_GALLIUM_SOURCES + \ - COMMON_BM_SOURCES + \ - DRIVER_SOURCES - -drivers = [ - softpipe, - i915simple -] - -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='i915tex_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], -) \ No newline at end of file +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + env.Append(CPPPATH = [ + '../intel', + 'server' + ]) + + #MINIGLX_SOURCES = server/intel_dri.c + + DRIVER_SOURCES = [ + 'intel_winsys_pipe.c', + 'intel_winsys_softpipe.c', + 'intel_winsys_i915.c', + 'intel_batchbuffer.c', + 'intel_swapbuffers.c', + 'intel_context.c', + 'intel_lock.c', + 'intel_screen.c', + 'intel_batchpool.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + COMMON_BM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + i915simple + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='i915tex_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index 218b89285f..5e98a36abc 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -3,30 +3,32 @@ Import('*') -env = env.Clone() +if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dri']: -env.Append(CPPPATH = [ - '#/src/mesa', - '#/src/mesa/main', -]) + env = env.Clone() -sources = [ - 'glxapi.c', - 'fakeglx.c', - 'xfonts.c', - 'xm_api.c', - 'xm_winsys.c', - 'xm_winsys_aub.c', - 'brw_aub.c', -] - -drivers = [ - softpipe, -] + env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/main', + ]) -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -env.SharedLibrary( - target ='GL', - source = sources, - LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], -) + sources = [ + 'glxapi.c', + 'fakeglx.c', + 'xfonts.c', + 'xm_api.c', + 'xm_winsys.c', + 'xm_winsys_aub.c', + 'brw_aub.c', + ] + + drivers = [ + softpipe, + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='GL', + source = sources, + LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'], + ) -- cgit v1.2.3 From fe1a2d1fffe69018e30158ee21ed9842384fd233 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Thu, 5 Jun 2008 15:07:03 -0600 Subject: egl: assorted fixes for Windows Note that int32_t is typedef'd both in p_compiler.h and eglplatform.h --- SConstruct | 1 + include/EGL/eglplatform.h | 20 ++++++++++++++++++-- include/GLES/glplatform.h | 2 -- src/gallium/include/pipe/p_compiler.h | 2 ++ 4 files changed, 21 insertions(+), 4 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 549ff647ea..8c8a82b38e 100644 --- a/SConstruct +++ b/SConstruct @@ -52,6 +52,7 @@ opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'intel', 'gdi'])) env = Environment( + MSVS_VERSION = '7.1', options = opts, ENV = os.environ) Help(opts.GenerateHelpText(env)) diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h index 3d71910e5f..2759a537a0 100644 --- a/include/EGL/eglplatform.h +++ b/include/EGL/eglplatform.h @@ -6,8 +6,10 @@ #define __eglplatform_h_ /* Windows calling convention boilerplate */ -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 +#if (defined(WIN32) || defined(_WIN32_WCE)) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#endif #include #endif @@ -47,6 +49,18 @@ etc. */ + +#if (defined(WIN32) || defined(_WIN32_WCE)) + +/** BEGIN Added for Windows **/ +typedef long int32_t; +typedef HDC NativeDisplayType; +typedef HWND NativeWindowType; +typedef HBITMAP NativePixmapType; +/** END Added for Windows **/ + +#elif defined(__gnu_linux__) + /** BEGIN Added for X (Mesa) **/ #include typedef Display *NativeDisplayType; @@ -54,6 +68,8 @@ typedef Window NativeWindowType; typedef Pixmap NativePixmapType; /** END Added for X (Mesa) **/ +#endif + /* EGL 1.2 types, renamed for consistency in EGL 1.3 */ typedef NativeDisplayType EGLNativeDisplayType; typedef NativePixmapType EGLNativePixmapType; diff --git a/include/GLES/glplatform.h b/include/GLES/glplatform.h index 56b3abcbe0..afbec74ea5 100644 --- a/include/GLES/glplatform.h +++ b/include/GLES/glplatform.h @@ -45,9 +45,7 @@ extern "C" { * Definition of GL_API and GL_APIENTRY *-----------------------------------------------------------------------*/ -#if defined(AEE_SIMULATOR) #define __GL_EXPORTS -#endif #ifdef _WIN32 # ifdef __GL_EXPORTS diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index b14260dd90..521ef2d189 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -58,7 +58,9 @@ typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; +#ifndef __eglplatform_h_ typedef __int32 int32_t; +#endif typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; -- cgit v1.2.3 From b04aa714afad014f2cdecc3ded9df0586f685921 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 6 Jun 2008 14:48:57 +0900 Subject: scons: Put the tool logic in a frontend tool. More logic can be shared between public and private branches this way. --- SConstruct | 36 ++----- common.py | 280 ----------------------------------------------- scons/gallium.py | 323 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+), 309 deletions(-) create mode 100644 scons/gallium.py (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 8c8a82b38e..4fddcc531e 100644 --- a/SConstruct +++ b/SConstruct @@ -53,8 +53,12 @@ opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, env = Environment( MSVS_VERSION = '7.1', - options = opts, - ENV = os.environ) + options = opts, + tools = ['gallium'], + toolpath = ['scons'], + ENV = os.environ, +) + Help(opts.GenerateHelpText(env)) # replicate options values in local variables @@ -82,25 +86,6 @@ Export([ ####################################################################### # Environment setup -# -# TODO: put the compiler specific settings in separate files -# TODO: auto-detect as much as possible - -if platform == 'winddk': - env.Tool('winddk', ['scons']) - - env.Append(CPPPATH = [ - env['SDK_INC_PATH'], - env['DDK_INC_PATH'], - env['WDM_INC_PATH'], - env['CRT_INC_PATH'], - ]) - -if platform == 'wince': - env.Tool('evc', ['scons']) - -common.generate(env) - # Includes env.Append(CPPPATH = [ @@ -111,13 +96,6 @@ env.Append(CPPPATH = [ ]) -# x86 assembly -if x86: - if gcc: - env.Append(CFLAGS = '-m32') - env.Append(CXXFLAGS = '-m32') - - # Posix if platform in ('posix', 'linux', 'freebsd', 'darwin'): env.Append(CPPDEFINES = [ @@ -182,6 +160,6 @@ Export('env') SConscript( 'src/SConscript', - build_dir = common.make_build_dir(env), + build_dir = env['build'], duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html ) diff --git a/common.py b/common.py index c82f3026dd..dd64e0f434 100644 --- a/common.py +++ b/common.py @@ -62,283 +62,3 @@ def AddOptions(opts): opts.Add(BoolOption('llvm', 'use LLVM', 'no')) opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) - -####################################################################### -# Quiet command lines -# -# See also http://www.scons.org/wiki/HidingCommandLinesInOutput - -def quietCommandLines(env): - env['CCCOMSTR'] = "Compiling $SOURCE ..." - env['CXXCOMSTR'] = "Compiling $SOURCE ..." - env['ARCOMSTR'] = "Archiving $TARGET ..." - env['RANLIBCOMSTR'] = "" - env['LINKCOMSTR'] = "Linking $TARGET ..." - - -####################################################################### -# Convenience Library Builder -# based on the stock StaticLibrary and SharedLibrary builders - -import SCons.Action -import SCons.Builder - -def createConvenienceLibBuilder(env): - """This is a utility function that creates the ConvenienceLibrary - Builder in an Environment if it is not there already. - - If it is already there, we return the existing one. - """ - - try: - convenience_lib = env['BUILDERS']['ConvenienceLibrary'] - except KeyError: - action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] - if env.Detect('ranlib'): - ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") - action_list.append(ranlib_action) - - convenience_lib = SCons.Builder.Builder(action = action_list, - emitter = '$LIBEMITTER', - prefix = '$LIBPREFIX', - suffix = '$LIBSUFFIX', - src_suffix = '$SHOBJSUFFIX', - src_builder = 'SharedObject') - env['BUILDERS']['ConvenienceLibrary'] = convenience_lib - env['BUILDERS']['Library'] = convenience_lib - - return convenience_lib - - -####################################################################### -# Build - -def make_build_dir(env): - # Put build output in a separate dir, which depends on the current configuration - # See also http://www.scons.org/wiki/AdvancedBuildExample - build_topdir = 'build' - build_subdir = env['platform'] - if env['dri']: - build_subdir += "-dri" - if env['llvm']: - build_subdir += "-llvm" - if env['machine'] != 'generic': - build_subdir += '-' + env['machine'] - if env['debug']: - build_subdir += "-debug" - if env['profile']: - build_subdir += "-profile" - build_dir = os.path.join(build_topdir, build_subdir) - # Place the .sconsign file on the builddir too, to avoid issues with different scons - # versions building the same source file - env.SConsignFile(os.path.join(build_dir, '.sconsign')) - return build_dir - - -####################################################################### -# Common environment generation code - -def generate(env): - # FIXME: this is already too late - #if env.get('quiet', False): - # quietCommandLines(env) - - # shortcuts - debug = env['debug'] - machine = env['machine'] - platform = env['platform'] - x86 = env['machine'] == 'x86' - gcc = env['platform'] in ('linux', 'freebsd', 'darwin') - msvc = env['platform'] in ('windows', 'winddk', 'wince') - - # C preprocessor options - cppdefines = [] - if debug: - cppdefines += ['DEBUG'] - else: - cppdefines += ['NDEBUG'] - if env['profile']: - cppdefines += ['PROFILE'] - if platform == 'windows': - cppdefines += [ - 'WIN32', - '_WINDOWS', - '_UNICODE', - 'UNICODE', - # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx, - 'WIN32_LEAN_AND_MEAN', - 'VC_EXTRALEAN', - '_CRT_SECURE_NO_DEPRECATE', - ] - if debug: - cppdefines += ['_DEBUG'] - if platform == 'winddk': - # Mimic WINDDK's builtin flags. See also: - # - WINDDK's bin/makefile.new i386mk.inc for more info. - # - buildchk_wxp_x86.log files, generated by the WINDDK's build - # - http://alter.org.ua/docs/nt_kernel/vc8_proj/ - cppdefines += [ - ('_X86_', '1'), - ('i386', '1'), - 'STD_CALL', - ('CONDITION_HANDLING', '1'), - ('NT_INST', '0'), - ('WIN32', '100'), - ('_NT1X_', '100'), - ('WINNT', '1'), - ('_WIN32_WINNT', '0x0501'), # minimum required OS version - ('WINVER', '0x0501'), - ('_WIN32_IE', '0x0603'), - ('WIN32_LEAN_AND_MEAN', '1'), - ('DEVL', '1'), - ('__BUILDMACHINE__', 'WinDDK'), - ('FPO', '0'), - ] - if debug: - cppdefines += [('DBG', 1)] - if platform == 'wince': - cppdefines += [ - ('_WIN32_WCE', '500'), - 'WCE_PLATFORM_STANDARDSDK_500', - '_i386_', - ('UNDER_CE', '500'), - 'UNICODE', - '_UNICODE', - '_X86_', - 'x86', - '_USRDLL', - 'TEST_EXPORTS' , - ] - if platform == 'windows': - cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_USER'] - if platform == 'winddk': - cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_DISPLAY'] - if platform == 'wince': - cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE'] - env.Append(CPPDEFINES = cppdefines) - - # C compiler options - cflags = [] - if gcc: - if debug: - cflags += ['-O0', '-g3'] - else: - cflags += ['-O3', '-g3'] - if env['profile']: - cflags += ['-pg'] - if env['machine'] == 'x86' and default_machine == 'x86_64': - cflags += ['-m32'] - if env['machine'] == 'x86_64' and default_machine == 'x86': - cflags += ['-m64'] - cflags += [ - '-Wall', - '-Wmissing-prototypes', - '-Wno-long-long', - '-ffast-math', - '-pedantic', - '-fmessage-length=0', # be nice to Eclipse - ] - if msvc: - # See also: - # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx - # - cl /? - if debug: - cflags += [ - '/Od', # disable optimizations - '/Oi', # enable intrinsic functions - '/Oy-', # disable frame pointer omission - ] - else: - cflags += [ - '/Ox', # maximum optimizations - '/Oi', # enable intrinsic functions - '/Os', # favor code space - ] - if env['profile']: - cflags += [ - '/Gh', # enable _penter hook function - '/GH', # enable _pexit hook function - ] - cflags += [ - '/W3', # warning level - #'/Wp64', # enable 64 bit porting warnings - ] - if platform == 'windows': - cflags += [ - # TODO - ] - if platform == 'winddk': - cflags += [ - '/Zl', # omit default library name in .OBJ - '/Zp8', # 8bytes struct member alignment - '/Gy', # separate functions for linker - '/Gm-', # disable minimal rebuild - '/WX', # treat warnings as errors - '/Gz', # __stdcall Calling convention - '/GX-', # disable C++ EH - '/GR-', # disable C++ RTTI - '/GF', # enable read-only string pooling - '/G6', # optimize for PPro, P-II, P-III - '/Ze', # enable extensions - '/Gi-', # disable incremental compilation - '/QIfdiv-', # disable Pentium FDIV fix - '/hotpatch', # prepares an image for hotpatching. - #'/Z7', #enable old-style debug info - ] - if platform == 'wince': - cflags += [ - '/Gs8192', - '/GF', # enable read-only string pooling - ] - # Put debugging information in a separate .pdb file for each object file as - # described in the scons manpage - env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb' - env.Append(CFLAGS = cflags) - env.Append(CXXFLAGS = cflags) - - # Linker options - linkflags = [] - if gcc: - if env['machine'] == 'x86' and default_machine == 'x86_64': - linkflags += ['-m32'] - if env['machine'] == 'x86_64' and default_machine == 'x86': - linkflags += ['-m64'] - if platform == 'winddk': - # See also: - # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx - linkflags += [ - '/merge:_PAGE=PAGE', - '/merge:_TEXT=.text', - '/section:INIT,d', - '/opt:ref', - '/opt:icf', - '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221', - '/incremental:no', - '/fullbuild', - '/release', - '/nodefaultlib', - '/wx', - '/debug', - '/debugtype:cv', - '/version:5.1', - '/osversion:5.1', - '/functionpadmin:5', - '/safeseh', - '/pdbcompress', - '/stack:0x40000,0x1000', - '/driver', - '/align:0x80', - '/subsystem:native,5.01', - '/base:0x10000', - - '/entry:DrvEnableDriver', - ] - env.Append(LINKFLAGS = linkflags) - - - createConvenienceLibBuilder(env) - - - # for debugging - #print env.Dump() - diff --git a/scons/gallium.py b/scons/gallium.py new file mode 100644 index 0000000000..1787adb312 --- /dev/null +++ b/scons/gallium.py @@ -0,0 +1,323 @@ +"""gallium + +Frontend-tool for Gallium3D architecture. + +""" + +# +# 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. +# + + +import os.path + +import SCons.Action +import SCons.Builder + + +def quietCommandLines(env): + # Quiet command lines + # See also http://www.scons.org/wiki/HidingCommandLinesInOutput + env['CCCOMSTR'] = "Compiling $SOURCE ..." + env['CXXCOMSTR'] = "Compiling $SOURCE ..." + env['ARCOMSTR'] = "Archiving $TARGET ..." + env['RANLIBCOMSTR'] = "" + env['LINKCOMSTR'] = "Linking $TARGET ..." + + +def createConvenienceLibBuilder(env): + """This is a utility function that creates the ConvenienceLibrary + Builder in an Environment if it is not there already. + + If it is already there, we return the existing one. + + Based on the stock StaticLibrary and SharedLibrary builders. + """ + + try: + convenience_lib = env['BUILDERS']['ConvenienceLibrary'] + except KeyError: + action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ] + if env.Detect('ranlib'): + ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR") + action_list.append(ranlib_action) + + convenience_lib = SCons.Builder.Builder(action = action_list, + emitter = '$LIBEMITTER', + prefix = '$LIBPREFIX', + suffix = '$LIBSUFFIX', + src_suffix = '$SHOBJSUFFIX', + src_builder = 'SharedObject') + env['BUILDERS']['ConvenienceLibrary'] = convenience_lib + env['BUILDERS']['Library'] = convenience_lib + + return convenience_lib + + +def generate(env): + """Common environment generation code""" + + # FIXME: this is already too late + #if env.get('quiet', False): + # quietCommandLines(env) + + # shortcuts + debug = env['debug'] + machine = env['machine'] + platform = env['platform'] + x86 = env['machine'] == 'x86' + gcc = env['platform'] in ('linux', 'freebsd', 'darwin') + msvc = env['platform'] in ('windows', 'winddk', 'wince') + + # Tool + if platform == 'winddk': + env.Tool('winddk') + elif platform == 'wince': + env.Tool('evc') + else: + env.Tool('default') + + # Put build output in a separate dir, which depends on the current + # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample + build_topdir = 'build' + build_subdir = env['platform'] + if env['dri']: + build_subdir += "-dri" + if env['llvm']: + build_subdir += "-llvm" + if env['machine'] != 'generic': + build_subdir += '-' + env['machine'] + if env['debug']: + build_subdir += "-debug" + if env['profile']: + build_subdir += "-profile" + build_dir = os.path.join(build_topdir, build_subdir) + # Place the .sconsign file in the build dir too, to avoid issues with + # different scons versions building the same source file + env['build'] = build_dir + env.SConsignFile(os.path.join(build_dir, '.sconsign')) + + # C preprocessor options + cppdefines = [] + if debug: + cppdefines += ['DEBUG'] + else: + cppdefines += ['NDEBUG'] + if env['profile']: + cppdefines += ['PROFILE'] + if platform == 'windows': + cppdefines += [ + 'WIN32', + '_WINDOWS', + '_UNICODE', + 'UNICODE', + # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx, + 'WIN32_LEAN_AND_MEAN', + 'VC_EXTRALEAN', + '_CRT_SECURE_NO_DEPRECATE', + ] + if debug: + cppdefines += ['_DEBUG'] + if platform == 'winddk': + # Mimic WINDDK's builtin flags. See also: + # - WINDDK's bin/makefile.new i386mk.inc for more info. + # - buildchk_wxp_x86.log files, generated by the WINDDK's build + # - http://alter.org.ua/docs/nt_kernel/vc8_proj/ + cppdefines += [ + ('_X86_', '1'), + ('i386', '1'), + 'STD_CALL', + ('CONDITION_HANDLING', '1'), + ('NT_INST', '0'), + ('WIN32', '100'), + ('_NT1X_', '100'), + ('WINNT', '1'), + ('_WIN32_WINNT', '0x0501'), # minimum required OS version + ('WINVER', '0x0501'), + ('_WIN32_IE', '0x0603'), + ('WIN32_LEAN_AND_MEAN', '1'), + ('DEVL', '1'), + ('__BUILDMACHINE__', 'WinDDK'), + ('FPO', '0'), + ] + if debug: + cppdefines += [('DBG', 1)] + if platform == 'wince': + cppdefines += [ + ('_WIN32_WCE', '500'), + 'WCE_PLATFORM_STANDARDSDK_500', + '_i386_', + ('UNDER_CE', '500'), + 'UNICODE', + '_UNICODE', + '_X86_', + 'x86', + '_USRDLL', + 'TEST_EXPORTS' , + ] + if platform == 'windows': + cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_USER'] + if platform == 'winddk': + cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_DISPLAY'] + if platform == 'wince': + cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE'] + env.Append(CPPDEFINES = cppdefines) + + # C preprocessor includes + if platform == 'winddk': + env.Append(CPPPATH = [ + env['SDK_INC_PATH'], + env['DDK_INC_PATH'], + env['WDM_INC_PATH'], + env['CRT_INC_PATH'], + ]) + + # C compiler options + cflags = [] + if gcc: + if debug: + cflags += ['-O0', '-g3'] + else: + cflags += ['-O3', '-g3'] + if env['profile']: + cflags += ['-pg'] + if env['machine'] == 'x86': + cflags += ['-m32'] + if env['machine'] == 'x86_64': + cflags += ['-m64'] + cflags += [ + '-Wall', + '-Wmissing-prototypes', + '-Wno-long-long', + '-ffast-math', + '-pedantic', + '-fmessage-length=0', # be nice to Eclipse + ] + if msvc: + # See also: + # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx + # - cl /? + if debug: + cflags += [ + '/Od', # disable optimizations + '/Oi', # enable intrinsic functions + '/Oy-', # disable frame pointer omission + ] + else: + cflags += [ + '/Ox', # maximum optimizations + '/Oi', # enable intrinsic functions + '/Os', # favor code space + ] + if env['profile']: + cflags += [ + '/Gh', # enable _penter hook function + '/GH', # enable _pexit hook function + ] + cflags += [ + '/W3', # warning level + #'/Wp64', # enable 64 bit porting warnings + ] + if platform == 'windows': + cflags += [ + # TODO + ] + if platform == 'winddk': + cflags += [ + '/Zl', # omit default library name in .OBJ + '/Zp8', # 8bytes struct member alignment + '/Gy', # separate functions for linker + '/Gm-', # disable minimal rebuild + '/WX', # treat warnings as errors + '/Gz', # __stdcall Calling convention + '/GX-', # disable C++ EH + '/GR-', # disable C++ RTTI + '/GF', # enable read-only string pooling + '/G6', # optimize for PPro, P-II, P-III + '/Ze', # enable extensions + '/Gi-', # disable incremental compilation + '/QIfdiv-', # disable Pentium FDIV fix + '/hotpatch', # prepares an image for hotpatching. + #'/Z7', #enable old-style debug info + ] + if platform == 'wince': + cflags += [ + '/Gs8192', + '/GF', # enable read-only string pooling + ] + # Automatic pdb generation + # See http://scons.tigris.org/issues/show_bug.cgi?id=1656 + env.EnsureSConsVersion(0, 98, 0) + env['PDB'] = '${TARGET.base}.pdb' + env.Append(CFLAGS = cflags) + env.Append(CXXFLAGS = cflags) + + # Linker options + linkflags = [] + if gcc: + if env['machine'] == 'x86': + linkflags += ['-m32'] + if env['machine'] == 'x86_64': + linkflags += ['-m64'] + if platform == 'winddk': + # See also: + # - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx + linkflags += [ + '/merge:_PAGE=PAGE', + '/merge:_TEXT=.text', + '/section:INIT,d', + '/opt:ref', + '/opt:icf', + '/ignore:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221', + '/incremental:no', + '/fullbuild', + '/release', + '/nodefaultlib', + '/wx', + '/debug', + '/debugtype:cv', + '/version:5.1', + '/osversion:5.1', + '/functionpadmin:5', + '/safeseh', + '/pdbcompress', + '/stack:0x40000,0x1000', + '/driver', + '/align:0x80', + '/subsystem:native,5.01', + '/base:0x10000', + + '/entry:DrvEnableDriver', + ] + env.Append(LINKFLAGS = linkflags) + + # Convenience Library Builder + createConvenienceLibBuilder(env) + + # for debugging + #print env.Dump() + + +def exists(env): + return 1 -- cgit v1.2.3 From 18953a8771054f02f9a9bef08bf323e19086fdac Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 6 Jun 2008 15:20:42 +0900 Subject: scons: Don't force MSVS 2003. --- SConstruct | 1 - 1 file changed, 1 deletion(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 4fddcc531e..4f19b16a0d 100644 --- a/SConstruct +++ b/SConstruct @@ -52,7 +52,6 @@ opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'intel', 'gdi'])) env = Environment( - MSVS_VERSION = '7.1', options = opts, tools = ['gallium'], toolpath = ['scons'], -- cgit v1.2.3 From fb4361a93d2bfdd69995d3421bfeb5a339dad5bf Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 27 Jun 2008 12:35:18 +0900 Subject: scons: Fix typo. --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 4f19b16a0d..a3bf5c5d57 100644 --- a/SConstruct +++ b/SConstruct @@ -44,7 +44,7 @@ else: opts = Options('config.py') common.AddOptions(opts) -opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetrackers, +opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers, ['mesa'])) opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell'])) -- cgit v1.2.3 From 6410e94b966148dde81b5121e53a250d7b530d91 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 13 Jul 2008 23:36:59 +0900 Subject: python: New state tracker which exposes the pipe driver to python scripts. Still under development. Just barely works. --- SConstruct | 7 +- src/gallium/SConscript | 2 + src/gallium/state_trackers/python/README | 32 ++ src/gallium/state_trackers/python/SConscript | 24 ++ src/gallium/state_trackers/python/gallium.i | 448 +++++++++++++++++++++ src/gallium/state_trackers/python/p_format.i | 152 +++++++ .../state_trackers/python/samples/simple.py | 158 ++++++++ src/gallium/state_trackers/python/st_device.c | 169 ++++++++ src/gallium/state_trackers/python/st_device.h | 83 ++++ .../state_trackers/python/st_softpipe_winsys.c | 321 +++++++++++++++ src/gallium/state_trackers/python/st_winsys.h | 58 +++ 11 files changed, 1450 insertions(+), 4 deletions(-) create mode 100644 src/gallium/state_trackers/python/README create mode 100644 src/gallium/state_trackers/python/SConscript create mode 100644 src/gallium/state_trackers/python/gallium.i create mode 100644 src/gallium/state_trackers/python/p_format.i create mode 100644 src/gallium/state_trackers/python/samples/simple.py create mode 100644 src/gallium/state_trackers/python/st_device.c create mode 100644 src/gallium/state_trackers/python/st_device.h create mode 100644 src/gallium/state_trackers/python/st_softpipe_winsys.c create mode 100644 src/gallium/state_trackers/python/st_winsys.h (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index a3bf5c5d57..6e166502f8 100644 --- a/SConstruct +++ b/SConstruct @@ -29,23 +29,22 @@ import common ####################################################################### # Configuration options +default_statetrackers = 'mesa' + if common.default_platform in ('linux', 'freebsd', 'darwin'): - default_statetrackers = 'all' default_drivers = 'softpipe,failover,i915simple,i965simple' default_winsys = 'xlib' elif common.default_platform in ('winddk',): - default_statetrackers = 'all' default_drivers = 'softpipe,i915simple' default_winsys = 'all' else: - default_statetrackers = 'all' default_drivers = 'all' default_winsys = 'all' opts = Options('config.py') common.AddOptions(opts) opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers, - ['mesa'])) + ['mesa', 'python'])) opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell'])) opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 2653f91bd2..6a3e7e77ed 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -25,3 +25,5 @@ SConscript([ for driver in env['drivers']: SConscript(os.path.join('drivers', driver, 'SConscript')) + +SConscript('state_trackers/python/SConscript') diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README new file mode 100644 index 0000000000..75341aa28c --- /dev/null +++ b/src/gallium/state_trackers/python/README @@ -0,0 +1,32 @@ +This directory contains Python bindings to Gallium3D. It looks like a state +tracker from the pipe driver perspective, and it looks like a pipe driver from +the python script perspective. + + +To build you'll need: +* Python (with development packages) +* SCons +* SWIG +* Python Imaging Library (for the samples) + +Invoke scons on the top dir as + + scons statetrackers=python + +To use do + + export PYTHONPATH=build/XXXX-XXXX-XXXX/gallium/state_trackers/python + +and then try running + + python src/gallium/state_trackers/python/samples/simple.py + +which should create a simple.png + + +This is still in experimental phase, and there many limitations to what you can +do with from Python. + + +-- +Jose Fonseca diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript new file mode 100644 index 0000000000..57a3fb2075 --- /dev/null +++ b/src/gallium/state_trackers/python/SConscript @@ -0,0 +1,24 @@ +Import('*') + +if 'python' in env['statetrackers']: + + env = env.Clone() + + env.Append(CPPPATH = '.') + + env.Tool('swig') + env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) + env.Append(SWIGFLAGS = ['-python', '-keyword']) + + env.ParseConfig('python-config --cflags --ldflags --libs') + + env.SharedLibrary( + target = '_gallium', + source = [ + 'gallium.i', + 'st_device.c', + 'st_softpipe_winsys.c', + ], + SHLIBPREFIX = '', + LIBS = softpipe + auxiliaries + env['LIBS'], + ) diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i new file mode 100644 index 0000000000..d6594f3a87 --- /dev/null +++ b/src/gallium/state_trackers/python/gallium.i @@ -0,0 +1,448 @@ + /************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca + */ + +%module gallium; + +%{ + +#include +#include + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "util/u_draw_quad.h" +#include "util/p_tile.h" +#include "cso_cache/cso_context.h" + +#include "st_device.h" + +%} + +%include "carrays.i" +%array_class(int, IntArray); +%array_class(float, FloatArray); + + +%rename(Device) st_device; +%rename(Context) st_context; +%rename(Texture) pipe_texture; +%rename(Surface) pipe_surface; + +%rename(Buffer) pipe_buffer; +%rename(BlendColor) pipe_blend_color; +%rename(Blend) pipe_blend_state; +%rename(Clip) pipe_clip_state; +%rename(ConstantBuffer) pipe_constant_buffer; +%rename(DepthStencilAlpha) pipe_depth_stencil_alpha_state; +%rename(FormatBlock) pipe_format_block; +%rename(Framebuffer) pipe_framebuffer_state; +%rename(PolyStipple) pipe_poly_stipple; +%rename(Rasterizer) pipe_rasterizer_state; +%rename(Sampler) pipe_sampler_state; +%rename(Scissor) pipe_scissor_state; +%rename(Shader) pipe_shader_state; +%rename(VertexBuffer) pipe_vertex_buffer; +%rename(VertexElement) pipe_vertex_element; +%rename(Viewport) pipe_viewport_state; + +%include "p_format.i"; +%include "pipe/p_defines.h"; +%include "pipe/p_state.h"; +%include "pipe/p_shader_tokens.h"; + + +%nodefaultctor; +%nodefaultdtor; + +struct st_device { +}; + +struct st_context { +}; + + +%extend st_device { + + st_device(int hardware = 0) { + return st_device_create(hardware ? TRUE : FALSE); + } + + ~st_device() { + st_device_destroy($self); + } + + const char * get_name( void ) { + return $self->screen->get_name($self->screen); + } + + const char * get_vendor( void ) { + return $self->screen->get_vendor($self->screen); + } + + /** + * Query an integer-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ + int get_param( int param ) { + return $self->screen->get_param($self->screen, param); + } + + /** + * Query a float-valued capability/parameter/limit + * \param param one of PIPE_CAP_x + */ + float get_paramf( int param ) { + return $self->screen->get_paramf($self->screen, param); + } + + /** + * Check if the given pipe_format is supported as a texture or + * drawing surface. + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ + int is_format_supported( enum pipe_format format, unsigned type ) { + return $self->screen->is_format_supported( $self->screen, format, type); + } + + struct st_context * + context_create(void) { + return st_context_create($self); + } + + struct pipe_texture * + texture_create( + enum pipe_format format, + unsigned width, + unsigned height, + unsigned depth = 1, + unsigned last_level = 0, + enum pipe_texture_target target = PIPE_TEXTURE_2D, + unsigned usage = 0 + ) { + struct pipe_texture templat; + memset(&templat, 0, sizeof(templat)); + templat.format = format; + pf_get_block(templat.format, &templat.block); + templat.width[0] = width; + templat.height[0] = height; + templat.depth[0] = depth; + templat.last_level = last_level; + templat.target = target; + templat.tex_usage = usage; + return $self->screen->texture_create($self->screen, &templat); + } + + struct pipe_buffer * + buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) { + return $self->screen->winsys->buffer_create($self->screen->winsys, alignment, usage, size); + } + +}; + + +%extend st_context { + + ~st_context() { + st_context_destroy($self); + } + + /* + * State functions (create/bind/destroy state objects) + */ + + void set_blend( const struct pipe_blend_state *state ) { + cso_set_blend($self->cso, state); + } + + void set_sampler( unsigned index, const struct pipe_sampler_state *state ) { + cso_single_sampler($self->cso, index, state); + cso_single_sampler_done($self->cso); + } + + void set_rasterizer( const struct pipe_rasterizer_state *state ) { + cso_set_rasterizer($self->cso, state); + } + + void set_depth_stencil_alpha(const struct pipe_depth_stencil_alpha_state *state) { + cso_set_depth_stencil_alpha($self->cso, state); + } + + + void * create_fs( const struct pipe_shader_state *state ) { + return $self->pipe->create_fs_state($self->pipe, state); + } + + void bind_fs( void *state_obj ) { + $self->pipe->bind_fs_state($self->pipe, state_obj); + } + + void delete_fs( void *state_obj ) { + $self->pipe->delete_fs_state($self->pipe, state_obj); + } + + void * create_vs( const struct pipe_shader_state *state ) { + return $self->pipe->create_vs_state($self->pipe, state); + } + + void bind_vs( void *state_obj ) { + $self->pipe->bind_vs_state($self->pipe, state_obj); + } + + void delete_vs( void *state_obj ) { + $self->pipe->delete_vs_state($self->pipe, state_obj); + } + + /* + * Parameter-like state (or properties) + */ + + void set_blend_color(const struct pipe_blend_color *state ) { + cso_set_blend_color($self->cso, state); + } + + void set_clip(const struct pipe_clip_state *state ) { + $self->pipe->set_clip_state($self->pipe, state); + } + + void set_constant_buffer(unsigned shader, unsigned index, + const struct pipe_constant_buffer *buf ) { + $self->pipe->set_constant_buffer($self->pipe, shader, index, buf); + } + + void set_framebuffer(const struct pipe_framebuffer_state *state ) { + cso_set_framebuffer($self->cso, state); + } + + void set_polygon_stipple(const struct pipe_poly_stipple *state ) { + $self->pipe->set_polygon_stipple($self->pipe, state); + } + + void set_scissor(const struct pipe_scissor_state *state ) { + $self->pipe->set_scissor_state($self->pipe, state); + } + + void set_viewport(const struct pipe_viewport_state *state) { + cso_set_viewport($self->cso, state); + } + + void set_sampler_texture(unsigned index, + struct pipe_texture *texture) { + pipe_texture_reference(&$self->sampler_textures[index], texture); + $self->pipe->set_sampler_textures($self->pipe, + PIPE_MAX_SAMPLERS, + $self->sampler_textures); + } + + void set_vertex_buffer(unsigned index, + const struct pipe_vertex_buffer *buffer) { + memcpy(&$self->vertex_buffers[index], buffer, sizeof(*buffer)); + $self->pipe->set_vertex_buffers($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_buffers); + } + + void set_vertex_element(unsigned index, + const struct pipe_vertex_element *element) { + memcpy(&$self->vertex_elements[index], element, sizeof(*element)); + $self->pipe->set_vertex_elements($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_elements); + } + + /* + * Draw functions + */ + + void draw_arrays(unsigned mode, unsigned start, unsigned count) { + $self->pipe->draw_arrays($self->pipe, mode, start, count); + } + + void draw_elements( struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) { + $self->pipe->draw_elements($self->pipe, indexBuffer, indexSize, mode, start, count); + } + + void draw_vertices(unsigned prim, + unsigned num_verts, + unsigned num_attribs, + const float *vertices) + { + struct pipe_context *pipe = $self->pipe; + struct pipe_winsys *winsys = pipe->winsys; + struct pipe_buffer *vbuf; + float *map; + unsigned size; + + size = num_verts * num_attribs * 4 * sizeof(float); + + vbuf = winsys->buffer_create(winsys, + 32, + PIPE_BUFFER_USAGE_VERTEX, + size); + if(!vbuf) + goto error1; + + map = winsys->buffer_map(winsys, vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); + if (!map) + goto error2; + memcpy(map, vertices, size); + pipe->winsys->buffer_unmap(pipe->winsys, vbuf); + + util_draw_vertex_buffer(pipe, vbuf, prim, num_verts, num_attribs); + +error2: + pipe_buffer_reference(pipe->winsys, &vbuf, NULL); +error1: + ; + } + + void draw_quad(float x0, float y0, float x1, float y1, float z = 0.0f) { + util_draw_texquad($self->pipe, x0, y0, x1, y1, z); + } + + void + flush(void) { + struct pipe_fence_handle *fence = NULL; + $self->pipe->flush($self->pipe, PIPE_FLUSH_RENDER_CACHE, &fence); + /* TODO: allow asynchronous operation */ + $self->pipe->winsys->fence_finish( $self->pipe->winsys, fence, 0 ); + $self->pipe->winsys->fence_reference( $self->pipe->winsys, &fence, NULL ); + } + + /* + * Surface functions + */ + + void surface_copy(int do_flip, + struct pipe_surface *dest, + unsigned destx, unsigned desty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) { + $self->pipe->surface_copy($self->pipe, do_flip, dest, destx, desty, src, srcx, srcy, width, height); + } + + void surface_fill(struct pipe_surface *dst, + unsigned x, unsigned y, + unsigned width, unsigned height, + unsigned value) { + $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value); + } + + void clear(struct pipe_surface *surface, unsigned value) { + $self->pipe->clear($self->pipe, surface, value); + } + +}; + + +%extend pipe_texture { + + ~pipe_texture() { + struct pipe_texture *ptr = $self; + pipe_texture_reference(&ptr, NULL); + } + + /** Get a surface which is a "view" into a texture */ + struct pipe_surface * + get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) + { + struct pipe_screen *screen = $self->screen; + return screen->get_tex_surface(screen, $self, face, level, zslice, usage); + } + +}; + + +%extend pipe_surface { + + ~pipe_surface() { + struct pipe_surface *ptr = $self; + pipe_surface_reference(&ptr, NULL); + } + + // gets mapped to pipe_surface_map automatically + void * map( unsigned flags ); + + // gets mapped to pipe_surface_unmap automatically + void unmap( void ); + + void + get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *p) { + pipe_get_tile_rgba($self, x, y, w, h, p); + } + + void + put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *p) { + pipe_put_tile_rgba($self, x, y, w, h, p); + } + + void + get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) { + pipe_get_tile_z($self, x, y, w, h, z); + } + + void + put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) { + pipe_put_tile_z($self, x, y, w, h, z); + } + +}; + + +%extend pipe_framebuffer_state { + + pipe_framebuffer_state(void) { + return CALLOC_STRUCT(pipe_framebuffer_state); + } + + ~pipe_framebuffer_state() { + unsigned index; + for(index = 0; index < PIPE_MAX_COLOR_BUFS; ++index) + pipe_surface_reference(&$self->cbufs[index], NULL); + pipe_surface_reference(&$self->zsbuf, NULL); + FREE($self); + } + + void + set_cbuf(unsigned index, struct pipe_surface *surface) { + pipe_surface_reference(&$self->cbufs[index], surface); + } + + void + set_zsbuf(struct pipe_surface *surface) { + pipe_surface_reference(&$self->zsbuf, surface); + } + +}; diff --git a/src/gallium/state_trackers/python/p_format.i b/src/gallium/state_trackers/python/p_format.i new file mode 100644 index 0000000000..51ad4bebcd --- /dev/null +++ b/src/gallium/state_trackers/python/p_format.i @@ -0,0 +1,152 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/* + * XXX: SWIG can't parse p_format.h, so we need to duplicate the relevant + * declarations here + */ + +%{ +#include "pipe/p_format.h" +%} + +enum pipe_format { + PIPE_FORMAT_NONE, + PIPE_FORMAT_A8R8G8B8_UNORM, + PIPE_FORMAT_X8R8G8B8_UNORM, + PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_FORMAT_B8G8R8X8_UNORM, + PIPE_FORMAT_A1R5G5B5_UNORM, + PIPE_FORMAT_A4R4G4B4_UNORM, + PIPE_FORMAT_R5G6B5_UNORM, + PIPE_FORMAT_A2B10G10R10_UNORM, + PIPE_FORMAT_L8_UNORM, + PIPE_FORMAT_A8_UNORM, + PIPE_FORMAT_I8_UNORM, + PIPE_FORMAT_A8L8_UNORM, + PIPE_FORMAT_L16_UNORM, + PIPE_FORMAT_YCBCR, + PIPE_FORMAT_YCBCR_REV, + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z32_FLOAT, + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_X8Z24_UNORM, + PIPE_FORMAT_Z24X8_UNORM, + PIPE_FORMAT_S8_UNORM, + PIPE_FORMAT_R64_FLOAT, + PIPE_FORMAT_R64G64_FLOAT, + PIPE_FORMAT_R64G64B64_FLOAT, + PIPE_FORMAT_R64G64B64A64_FLOAT, + PIPE_FORMAT_R32_FLOAT, + PIPE_FORMAT_R32G32_FLOAT, + PIPE_FORMAT_R32G32B32_FLOAT, + PIPE_FORMAT_R32G32B32A32_FLOAT, + PIPE_FORMAT_R32_UNORM, + PIPE_FORMAT_R32G32_UNORM, + PIPE_FORMAT_R32G32B32_UNORM, + PIPE_FORMAT_R32G32B32A32_UNORM, + PIPE_FORMAT_R32_USCALED, + PIPE_FORMAT_R32G32_USCALED, + PIPE_FORMAT_R32G32B32_USCALED, + PIPE_FORMAT_R32G32B32A32_USCALED, + PIPE_FORMAT_R32_SNORM, + PIPE_FORMAT_R32G32_SNORM, + PIPE_FORMAT_R32G32B32_SNORM, + PIPE_FORMAT_R32G32B32A32_SNORM, + PIPE_FORMAT_R32_SSCALED, + PIPE_FORMAT_R32G32_SSCALED, + PIPE_FORMAT_R32G32B32_SSCALED, + PIPE_FORMAT_R32G32B32A32_SSCALED, + PIPE_FORMAT_R16_UNORM, + PIPE_FORMAT_R16G16_UNORM, + PIPE_FORMAT_R16G16B16_UNORM, + PIPE_FORMAT_R16G16B16A16_UNORM, + PIPE_FORMAT_R16_USCALED, + PIPE_FORMAT_R16G16_USCALED, + PIPE_FORMAT_R16G16B16_USCALED, + PIPE_FORMAT_R16G16B16A16_USCALED, + PIPE_FORMAT_R16_SNORM, + PIPE_FORMAT_R16G16_SNORM, + PIPE_FORMAT_R16G16B16_SNORM, + PIPE_FORMAT_R16G16B16A16_SNORM, + PIPE_FORMAT_R16_SSCALED, + PIPE_FORMAT_R16G16_SSCALED, + PIPE_FORMAT_R16G16B16_SSCALED, + PIPE_FORMAT_R16G16B16A16_SSCALED, + PIPE_FORMAT_R8_UNORM, + PIPE_FORMAT_R8G8_UNORM, + PIPE_FORMAT_R8G8B8_UNORM, + PIPE_FORMAT_R8G8B8A8_UNORM, + PIPE_FORMAT_R8G8B8X8_UNORM, + PIPE_FORMAT_R8_USCALED, + PIPE_FORMAT_R8G8_USCALED, + PIPE_FORMAT_R8G8B8_USCALED, + PIPE_FORMAT_R8G8B8A8_USCALED, + PIPE_FORMAT_R8G8B8X8_USCALED, + PIPE_FORMAT_R8_SNORM, + PIPE_FORMAT_R8G8_SNORM, + PIPE_FORMAT_R8G8B8_SNORM, + PIPE_FORMAT_R8G8B8A8_SNORM, + PIPE_FORMAT_R8G8B8X8_SNORM, + PIPE_FORMAT_B6G5R5_SNORM, + PIPE_FORMAT_A8B8G8R8_SNORM, + PIPE_FORMAT_X8B8G8R8_SNORM, + PIPE_FORMAT_R8_SSCALED, + PIPE_FORMAT_R8G8_SSCALED, + PIPE_FORMAT_R8G8B8_SSCALED, + PIPE_FORMAT_R8G8B8A8_SSCALED, + PIPE_FORMAT_R8G8B8X8_SSCALED, + PIPE_FORMAT_R32_FIXED, + PIPE_FORMAT_R32G32_FIXED, + PIPE_FORMAT_R32G32B32_FIXED, + PIPE_FORMAT_R32G32B32A32_FIXED, + + PIPE_FORMAT_L8_SRGB, + PIPE_FORMAT_A8_L8_SRGB, + PIPE_FORMAT_R8G8B8_SRGB, + PIPE_FORMAT_R8G8B8A8_SRGB, + PIPE_FORMAT_R8G8B8X8_SRGB, + + PIPE_FORMAT_X8UB8UG8SR8S_NORM, + PIPE_FORMAT_B6UG5SR5S_NORM, + + PIPE_FORMAT_DXT1_RGB, + PIPE_FORMAT_DXT1_RGBA, + PIPE_FORMAT_DXT3_RGBA, + PIPE_FORMAT_DXT5_RGBA, +}; + + +struct pipe_format_block +{ + unsigned size; + unsigned width; + unsigned height; +}; + diff --git a/src/gallium/state_trackers/python/samples/simple.py b/src/gallium/state_trackers/python/samples/simple.py new file mode 100644 index 0000000000..77e182b644 --- /dev/null +++ b/src/gallium/state_trackers/python/samples/simple.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python +########################################################################## +# +# 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. +# +########################################################################## + + +from gallium import * + + +def save_image(filename, surface): + pixels = FloatArray(surface.height*surface.width*4) + surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) + + import Image + outimage = Image.new( + mode='RGB', + size=(surface.width, surface.height), + color=(0,0,0)) + outpixels = outimage.load() + for y in range(0, surface.height): + for x in range(0, surface.width): + offset = (y*surface.width + x)*4 + r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] + outpixels[x, y] = r, g, b + outimage.save(filename, "PNG") + + +def test(dev): + ctx = dev.context_create() + + width = 256 + height = 256 + + # disabled blending/masking + blend = Blend() + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.colormask = PIPE_MASK_RGBA + ctx.set_blend(blend) + + # no-op depth/stencil/alpha + depth_stencil_alpha = DepthStencilAlpha() + ctx.set_depth_stencil_alpha(depth_stencil_alpha) + + # rasterizer + rasterizer = Rasterizer() + rasterizer.front_winding = PIPE_WINDING_CW + rasterizer.cull_mode = PIPE_WINDING_NONE + rasterizer.bypass_clipping = 1 + #rasterizer.bypass_vs = 1 + ctx.set_rasterizer(rasterizer) + + # viewport (identity, we setup vertices in wincoords) + viewport = Viewport() + scale = FloatArray(4) + scale[0] = 1.0 + scale[1] = 1.0 + scale[2] = 1.0 + scale[3] = 1.0 + viewport.scale = scale + translate = FloatArray(4) + translate[0] = 0.0 + translate[1] = 0.0 + translate[2] = 0.0 + translate[3] = 0.0 + viewport.translate = translate + ctx.set_viewport(viewport) + + # samplers + sampler = Sampler() + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.normalized_coords = 1 + ctx.set_sampler(0, sampler) + + # texture + texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, height, usage=PIPE_TEXTURE_USAGE_RENDER_TARGET) + ctx.set_sampler_texture(0, texture) + + # drawing dest + surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE) + fb = Framebuffer() + fb.width = surface.width + fb.height = surface.height + fb.num_cbufs = 1 + fb.set_cbuf(0, surface) + ctx.set_framebuffer(fb) + + # vertex shader + # vs = Shader() + #ctx.set_vertex_shader(vs) + + # fragment shader + #fs = Shader() + #ctx.set_fragment_shader(fs) + + if 0: + nverts = 4 + nattrs = 1 + vertices = FloatArray(n_verts * nattrs * 4) + + # init vertex data that doesn't change + for i in range(nverts): + for j in range(nattrs): + vertices[(i*nattrs +j)*4 + 0] = 0.0 + vertices[(i*nattrs +j)*4 + 1] = 0.0 + vertices[(i*nattrs +j)*4 + 2] = 0.0 + vertices[(i*nattrs +j)*4 + 3] = 0.0 + + ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, + 4, # verts + 2, # attribs/vert + vertices) + else: + ctx.draw_quad(32.0, 32.0, 224.0, 224.0) + + ctx.flush() + + save_image("simple.png", surface) + + + +def main(): + dev = Device(0) + test(dev) + + +if __name__ == '__main__': + main() diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c new file mode 100644 index 0000000000..430a7af176 --- /dev/null +++ b/src/gallium/state_trackers/python/st_device.c @@ -0,0 +1,169 @@ +/************************************************************************** + * + * 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 "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_inlines.h" +#include "cso_cache/cso_context.h" +#include "util/u_simple_shaders.h" +#include "st_device.h" +#include "st_winsys.h" + + +static void +st_device_really_destroy(struct st_device *st_dev) +{ + if(st_dev->screen) + st_dev->st_ws->screen_destroy(st_dev->screen); + + FREE(st_dev); +} + + +void +st_device_destroy(struct st_device *st_dev) +{ + if(!--st_dev->refcount) + st_device_really_destroy(st_dev); +} + + +static struct st_device * +st_device_create_from_st_winsys(const struct st_winsys *st_ws) +{ + struct st_device *st_dev; + + if(!st_ws->screen_create || + !st_ws->screen_destroy || + !st_ws->context_create || + !st_ws->context_destroy) + return NULL; + + st_dev = CALLOC_STRUCT(st_device); + if(!st_dev) + return NULL; + + st_dev->st_ws = st_ws; + + st_dev->screen = st_ws->screen_create(); + if(!st_dev->screen) + st_device_destroy(st_dev); + + return st_dev; +} + + +struct st_device * +st_device_create(boolean hardware) { +#if 0 + if(hardware) + return st_device_create_from_st_winsys(&st_hardware_winsys); + else +#endif + return st_device_create_from_st_winsys(&st_software_winsys); +} + + +void +st_context_destroy(struct st_context *st_ctx) +{ + unsigned i; + + if(st_ctx) { + struct st_device *st_dev = st_ctx->st_dev; + + if(st_ctx->vs) { + st_ctx->pipe->bind_vs_state(st_ctx->pipe, NULL); + st_ctx->pipe->delete_vs_state(st_ctx->pipe, st_ctx->vs); + } + + if(st_ctx->fs) { + st_ctx->pipe->bind_fs_state(st_ctx->pipe, NULL); + st_ctx->pipe->delete_fs_state(st_ctx->pipe, st_ctx->fs); + } + + if(st_ctx->cso) + cso_destroy_context(st_ctx->cso); + + if(st_ctx->pipe) + st_ctx->st_dev->st_ws->context_destroy(st_ctx->pipe); + + for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) + pipe_texture_reference(&st_ctx->sampler_textures[i], NULL); + + FREE(st_ctx); + + if(!--st_dev->refcount) + st_device_really_destroy(st_dev); + } +} + + +struct st_context * +st_context_create(struct st_device *st_dev) +{ + struct st_context *st_ctx; + + st_ctx = CALLOC_STRUCT(st_context); + if(!st_ctx) + return NULL; + + st_ctx->st_dev = st_dev; + ++st_dev->refcount; + + st_ctx->pipe = st_dev->st_ws->context_create(st_dev->screen); + if(!st_ctx->pipe) + st_context_destroy(st_ctx); + + st_ctx->cso = cso_create_context(st_ctx->pipe); + if(!st_ctx->cso) + st_context_destroy(st_ctx); + + /* vertex shader */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + st_ctx->vs = util_make_vertex_passthrough_shader(st_ctx->pipe, + 2, + semantic_names, + semantic_indexes, + &st_ctx->vert_shader); + } + + /* fragment shader */ + st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe, + &st_ctx->frag_shader); + + st_ctx->pipe->bind_fs_state(st_ctx->pipe, st_ctx->fs); + st_ctx->pipe->bind_vs_state(st_ctx->pipe, st_ctx->vs); + + return st_ctx; +} diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h new file mode 100644 index 0000000000..46db20acd7 --- /dev/null +++ b/src/gallium/state_trackers/python/st_device.h @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef ST_DEVICE_H_ +#define ST_DEVICE_H_ + + +#include "pipe/p_state.h" + +struct cso_context; +struct pipe_screen; +struct pipe_context; +struct st_winsys; + + +struct st_context { + struct st_device *st_dev; + + struct pipe_context *pipe; + + struct cso_context *cso; + + struct pipe_shader_state vert_shader; + struct pipe_shader_state frag_shader; + + void *vs; + void *fs; + + struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS]; + struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; +}; + + +struct st_device { + const struct st_winsys *st_ws; + + struct pipe_screen *screen; + + /* FIXME: we also need to refcount for textures and surfaces... */ + unsigned refcount; +}; + + +struct st_context * +st_context_create(struct st_device *st_dev); + +void +st_context_destroy(struct st_context *st_ctx); + +struct st_device * +st_device_create(boolean hardware); + +void +st_device_destroy(struct st_device *st_dev); + + +#endif /* ST_DEVICE_H_ */ diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c new file mode 100644 index 0000000000..964d60de1d --- /dev/null +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -0,0 +1,321 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +/** + * @file + * Softpipe support. + * + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "softpipe/sp_winsys.h" +#include "st_winsys.h" + + +struct st_softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; + void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct st_softpipe_buffer * +st_softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct st_softpipe_buffer *)buf; +} + + +static void * +st_softpipe_buffer_map(struct pipe_winsys *winsys, + struct pipe_buffer *buf, + unsigned flags) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = st_softpipe_buf->data; + return st_softpipe_buf->mapped; +} + + +static void +st_softpipe_buffer_unmap(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); + st_softpipe_buf->mapped = NULL; +} + + +static void +st_softpipe_buffer_destroy(struct pipe_winsys *winsys, + struct pipe_buffer *buf) +{ + struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); + + if (oldBuf->data) { + if (!oldBuf->userBuffer) + align_free(oldBuf->data); + + oldBuf->data = NULL; + } + + FREE(oldBuf); +} + + +static void +st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, + struct pipe_surface *surf, + void *context_private) +{ +} + + + +static const char * +st_softpipe_get_name(struct pipe_winsys *winsys) +{ + return "softpipe"; +} + + +static struct pipe_buffer * +st_softpipe_buffer_create(struct pipe_winsys *winsys, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); + + buffer->base.refcount = 1; + buffer->base.alignment = alignment; + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +st_softpipe_user_buffer_create(struct pipe_winsys *winsys, + void *ptr, + unsigned bytes) +{ + struct st_softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(st_softpipe_buffer); + if(!buffer) + return NULL; + + buffer->base.refcount = 1; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ + return (n + multiple - 1) & ~(multiple - 1); +} + + +static int +st_softpipe_surface_alloc_storage(struct pipe_winsys *winsys, + struct pipe_surface *surf, + unsigned width, unsigned height, + enum pipe_format format, + unsigned flags, + unsigned tex_usage) +{ + const unsigned alignment = 64; + + surf->width = width; + surf->height = height; + surf->format = format; + pf_get_block(format, &surf->block); + surf->nblocksx = pf_get_nblocksx(&surf->block, width); + surf->nblocksy = pf_get_nblocksy(&surf->block, height); + surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); + surf->usage = flags; + + assert(!surf->buffer); + surf->buffer = winsys->buffer_create(winsys, alignment, + PIPE_BUFFER_USAGE_PIXEL, + surf->stride * surf->nblocksy); + if(!surf->buffer) + return -1; + + return 0; +} + + +static struct pipe_surface * +st_softpipe_surface_alloc(struct pipe_winsys *winsys) +{ + struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + + assert(winsys); + + surface->refcount = 1; + surface->winsys = winsys; + + return surface; +} + + +static void +st_softpipe_surface_release(struct pipe_winsys *winsys, + struct pipe_surface **s) +{ + struct pipe_surface *surf = *s; + assert(!surf->texture); + surf->refcount--; + if (surf->refcount == 0) { + if (surf->buffer) + pipe_buffer_reference(winsys, &surf->buffer, NULL); + free(surf); + } + *s = NULL; +} + + +static void +st_softpipe_fence_reference(struct pipe_winsys *winsys, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ +} + + +static int +st_softpipe_fence_signalled(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static int +st_softpipe_fence_finish(struct pipe_winsys *winsys, + struct pipe_fence_handle *fence, + unsigned flag) +{ + return 0; +} + + +static void +st_softpipe_screen_destroy(struct pipe_screen *screen) +{ + struct pipe_winsys *winsys = screen->winsys; + + screen->destroy(screen); + + FREE(winsys); +} + + +static struct pipe_screen * +st_softpipe_screen_create(void) +{ + static struct pipe_winsys *winsys; + struct pipe_screen *screen; + + winsys = CALLOC_STRUCT(pipe_winsys); + if(!winsys) + return NULL; + + winsys->buffer_create = st_softpipe_buffer_create; + winsys->user_buffer_create = st_softpipe_user_buffer_create; + winsys->buffer_map = st_softpipe_buffer_map; + winsys->buffer_unmap = st_softpipe_buffer_unmap; + winsys->buffer_destroy = st_softpipe_buffer_destroy; + + winsys->surface_alloc = st_softpipe_surface_alloc; + winsys->surface_alloc_storage = st_softpipe_surface_alloc_storage; + winsys->surface_release = st_softpipe_surface_release; + + winsys->fence_reference = st_softpipe_fence_reference; + winsys->fence_signalled = st_softpipe_fence_signalled; + winsys->fence_finish = st_softpipe_fence_finish; + + winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; + winsys->get_name = st_softpipe_get_name; + + screen = softpipe_create_screen(winsys); + if(!screen) + FREE(winsys); + + return screen; +} + + +static void +st_softpipe_context_destroy(struct pipe_context *pipe) +{ + pipe->destroy(pipe); +} + + +static struct pipe_context * +st_softpipe_context_create(struct pipe_screen *screen) +{ + return softpipe_create(screen, screen->winsys, NULL); +} + + +const struct st_winsys st_software_winsys = { + &st_softpipe_screen_create, + &st_softpipe_screen_destroy, + &st_softpipe_context_create, + &st_softpipe_context_destroy +}; diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h new file mode 100644 index 0000000000..992fc9ab4b --- /dev/null +++ b/src/gallium/state_trackers/python/st_winsys.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef ST_WINSYS_H_ +#define ST_WINSYS_H_ + + +struct pipe_screen; +struct pipe_context; + + +struct st_winsys +{ + struct pipe_screen * + (*screen_create)(void); + + void + (*screen_destroy)(struct pipe_screen *screen); + + struct pipe_context * + (*context_create)(struct pipe_screen *screen); + + void + (*context_destroy)(struct pipe_context *pipe); +}; + + +extern const struct st_winsys st_software_winsys; + +extern const struct st_winsys st_hardware_winsys; + + +#endif /* ST_WINSYS_H_ */ -- cgit v1.2.3 From 2c4349aa3ac9a6d5ee1f7b1aeb5eb0ee1cb54690 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Jul 2008 07:56:42 +0900 Subject: python: Move the python scons code to a separate tool module. --- SConstruct | 2 +- scons/python.py | 71 ++++++++++++++++++++++++++++ src/gallium/state_trackers/python/SConscript | 44 +++-------------- 3 files changed, 79 insertions(+), 38 deletions(-) create mode 100644 scons/python.py (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 6e166502f8..fe27ceafe7 100644 --- a/SConstruct +++ b/SConstruct @@ -53,7 +53,7 @@ opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, env = Environment( options = opts, tools = ['gallium'], - toolpath = ['scons'], + toolpath = ['#scons'], ENV = os.environ, ) diff --git a/scons/python.py b/scons/python.py new file mode 100644 index 0000000000..e1acc775b6 --- /dev/null +++ b/scons/python.py @@ -0,0 +1,71 @@ +"""gallium + +Frontend-tool for Gallium3D architecture. + +""" + +# +# 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. +# + + +import sys +import os.path + + +def generate(env): + + # http://www.scons.org/wiki/PythonExtensions + #env.AppendUnique(CPPATH = [distutils.sysconfig.get_python_inc()]) + #distutils.sysconfig.get_config_vars('SO') + + env['SHLIBPREFIX'] = '' + + if sys.platform in ['linux2']: + env.ParseConfig('python-config --cflags --ldflags --libs') + + if sys.platform in ['windows']: + python_root = sys.prefix + python_version = '%u%u' % sys.version_info[:2] + python_include = os.path.join(python_root, 'include') + python_libs = os.path.join(python_root, 'libs') + python_lib = os.path.join(python_libs, 'python' + python_version + '.lib') + + env.Append(CPPPATH = [python_include]) + env.Append(LIBPATH = [python_libs]) + env.Append(LIBS = ['python' + python_version + '.lib']) + env.Replace(SHLIBSUFFIX = '.pyd') + + # XXX; python25_d.lib is not included in Python for windows, and + # we'll get missing symbols unless we undefine _DEBUG + cppdefines = env['CPPDEFINES'] + cppdefines = [define for define in cppdefines if define != '_DEBUG'] + env.Replace(CPPDEFINES = cppdefines) + + # for debugging + #print env.Dump() + + +def exists(env): + return 1 diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index 854cd83b7c..687c46bfd7 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -7,50 +7,20 @@ if 'python' in env['statetrackers']: env = env.Clone() - env.Append(CPPPATH = '.') + env.Tool('python') env.Tool('swig') env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) env.Append(SWIGFLAGS = ['-python', '-keyword']) - # http://www.scons.org/wiki/PythonExtensions - #env.AppendUnique(CPPATH = [distutils.sysconfig.get_python_inc()]) - #distutils.sysconfig.get_config_vars('SO') - - env['SHLIBPREFIX'] = '' - - if platform in ['linux']: - env.ParseConfig('python-config --cflags --ldflags --libs') - - if platform in ['windows']: - python_root = sys.prefix - python_version = '%u%u' % sys.version_info[:2] - python_include = os.path.join(python_root, 'include') - python_libs = os.path.join(python_root, 'libs') - python_lib = os.path.join(python_libs, 'python' + python_version + '.lib') - - env.Append(CPPPATH = [python_include]) - env.Append(LIBPATH = [python_libs]) - env.Append(LIBS = ['python' + python_version + '.lib']) - env.Replace(SHLIBSUFFIX = '.pyd') - - if env['debug']: - # XXX; python25_d.lib is not included in Python for windows, and - # we'll get missing symbols unless we undefine _DEBUG - cppdefines = env['CPPDEFINES'] - cppdefines = [define for define in cppdefines if define != '_DEBUG'] - env.Replace(CPPDEFINES = cppdefines) - - # http://www.swig.org/Doc1.3/Windows.html - env['ENV']['PYTHON_INCLUDE'] = python_include - env['ENV']['PYTHON_LIB'] = python_lib - + env.Append(CPPPATH = '.') + env.SharedLibrary( - target = '_gallium', - source = [ - 'gallium.i', + target = '_gallium', + source = [ + 'gallium.i', 'st_device.c', 'st_softpipe_winsys.c', - ], + ], LIBS = softpipe + auxiliaries + env['LIBS'], ) -- cgit v1.2.3 From 35355f7610b69dcd2fdba451db4554478fe0acaa Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 6 Aug 2008 21:36:25 +0100 Subject: trace: New pipe driver to trace incoming calls. Only pipe_screen calls traced, and only linux supported, for now. --- SConstruct | 2 +- src/gallium/drivers/trace/README | 37 ++++ src/gallium/drivers/trace/SConscript | 15 ++ src/gallium/drivers/trace/tr_context.c | 41 ++++ src/gallium/drivers/trace/tr_context.h | 58 +++++ src/gallium/drivers/trace/tr_dump.c | 329 ++++++++++++++++++++++++++++ src/gallium/drivers/trace/tr_dump.h | 102 +++++++++ src/gallium/drivers/trace/tr_screen.c | 385 +++++++++++++++++++++++++++++++++ src/gallium/drivers/trace/tr_screen.h | 65 ++++++ src/gallium/drivers/trace/tr_state.c | 72 ++++++ src/gallium/drivers/trace/tr_state.h | 44 ++++ src/gallium/drivers/trace/tr_stream.c | 100 +++++++++ src/gallium/drivers/trace/tr_stream.h | 52 +++++ 13 files changed, 1301 insertions(+), 1 deletion(-) create mode 100644 src/gallium/drivers/trace/README create mode 100644 src/gallium/drivers/trace/SConscript create mode 100644 src/gallium/drivers/trace/tr_context.c create mode 100644 src/gallium/drivers/trace/tr_context.h create mode 100644 src/gallium/drivers/trace/tr_dump.c create mode 100644 src/gallium/drivers/trace/tr_dump.h create mode 100644 src/gallium/drivers/trace/tr_screen.c create mode 100644 src/gallium/drivers/trace/tr_screen.h create mode 100644 src/gallium/drivers/trace/tr_state.c create mode 100644 src/gallium/drivers/trace/tr_state.h create mode 100644 src/gallium/drivers/trace/tr_stream.c create mode 100644 src/gallium/drivers/trace/tr_stream.h (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index fe27ceafe7..ee96bc5ab2 100644 --- a/SConstruct +++ b/SConstruct @@ -46,7 +46,7 @@ common.AddOptions(opts) opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers, ['mesa', 'python'])) opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, - ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell'])) + ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace'])) opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'intel', 'gdi'])) diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README new file mode 100644 index 0000000000..81da610bd5 --- /dev/null +++ b/src/gallium/drivers/trace/README @@ -0,0 +1,37 @@ +This directory contains a Gallium3D pipe driver which traces all incoming calls. + +To build, invoke scons on the top dir as + + scons statetrackers=mesa drivers=softpipe,i915simple,trace winsys=xlib + +To use do + + ln -s libGL.so build/linux-x86-debug/gallium/winsys/xlib/libGL.so.1 + export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/gallium/winsys/xlib + export GALLIUM_TRACE=y + +ensure the right libGL.so is being picked by doing + + ldd `which glxingo` + +and then try running + + glxinfo + +which should create a gallium.*.trace file, which is an XML file. You can view +copying trace.xsl and trace.css to the same directory, and opening with a +XSLT capable browser like Firefox or Internet Explorer. It often happens that +the trace file was not properly terminated, and a + + + +closing tag is missing from the file end. Add it before try to open or +further transform it by doing + + echo '' >> gallium.??.trace + + +This is still work in progress. + +-- +Jose Fonseca diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript new file mode 100644 index 0000000000..30225b5a54 --- /dev/null +++ b/src/gallium/drivers/trace/SConscript @@ -0,0 +1,15 @@ +Import('*') + +env = env.Clone() + +trace = env.ConvenienceLibrary( + target = 'trace', + source = [ + 'tr_context.c', + 'tr_dump.c', + 'tr_screen.c', + 'tr_state.c', + 'tr_stream.c', + ]) + +Export('trace') \ No newline at end of file diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c new file mode 100644 index 0000000000..67a67b3da6 --- /dev/null +++ b/src/gallium/drivers/trace/tr_context.c @@ -0,0 +1,41 @@ +/************************************************************************** + * + * 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 "pipe/p_util.h" + +#include "tr_stream.h" +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_context.h" + + +struct pipe_context * +trace_context_create(struct pipe_context *pipe) +{ + /* TODO */ + return pipe; +} diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h new file mode 100644 index 0000000000..75b8d11a7a --- /dev/null +++ b/src/gallium/drivers/trace/tr_context.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TR_CONTEXT_H_ +#define TR_CONTEXT_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_context.h" + + +struct trace_context +{ + struct pipe_context base; + + /* TODO */ +}; + + +static INLINE struct trace_context * +trace_context(struct pipe_context *context) +{ + assert(context); + return (struct trace_context *)context; +} + + + +struct pipe_context * +trace_context_create(struct pipe_context *context); + + +#endif /* TR_CONTEXT_H_ */ diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c new file mode 100644 index 0000000000..30c0986363 --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump.c @@ -0,0 +1,329 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * @file + * Trace dumping functions. + * + * For now we just use standard XML for dumping the trace calls, as this is + * simple to write, parse, and visually inspect, but the actual representation + * is abstracted out of this file, so that we can switch to a binary + * representation if/when it becomes justified. + * + * @author Jose Fonseca + */ + + +#include "pipe/p_compiler.h" +#include "util/u_string.h" + +#include "tr_stream.h" +#include "tr_dump.h" + + +static INLINE void +trace_dump_write(struct trace_stream *stream, const char *s) +{ + trace_stream_write(stream, s, strlen(s)); +} + + +static INLINE void +trace_dump_writef(struct trace_stream *stream, const char *format, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, format); + util_vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + trace_dump_write(stream, buf); +} + + +static INLINE void +trace_dump_escape(struct trace_stream *stream, const char *str) +{ + const unsigned char *p = (const unsigned char *)str; + unsigned char c; + while((c = *p++) != 0) { + if(c == '<') + trace_dump_write(stream, "<"); + else if(c == '>') + trace_dump_write(stream, ">"); + else if(c == '&') + trace_dump_write(stream, "&"); + else if(c == '\'') + trace_dump_write(stream, "'"); + else if(c == '\"') + trace_dump_write(stream, """); + else if(c >= 0x20 && c <= 0x7e) + trace_dump_writef(stream, "%c", c); + else + trace_dump_writef(stream, "&#%u;", c); + } +} + + +static INLINE void +trace_dump_indent(struct trace_stream *stream, unsigned level) +{ + unsigned i; + for(i = 0; i < level; ++i) + trace_dump_write(stream, "\t"); +} + + +static INLINE void +trace_dump_newline(struct trace_stream *stream) +{ + trace_dump_write(stream, "\n"); +} + + +static INLINE void +trace_dump_tag(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, "/>"); +} + + +static INLINE void +trace_dump_tag_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, ">"); +} + +static INLINE void +trace_dump_tag_begin1(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "='"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "'>"); +} + + +static INLINE void +trace_dump_tag_begin2(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1, + const char *attr2, const char *value2) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr2); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value2); + trace_dump_write(stream, "\'>"); +} + + +static INLINE void +trace_dump_tag_begin3(struct trace_stream *stream, + const char *name, + const char *attr1, const char *value1, + const char *attr2, const char *value2, + const char *attr3, const char *value3) +{ + trace_dump_write(stream, "<"); + trace_dump_write(stream, name); + trace_dump_write(stream, " "); + trace_dump_write(stream, attr1); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value1); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr2); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value2); + trace_dump_write(stream, "\' "); + trace_dump_write(stream, attr3); + trace_dump_write(stream, "=\'"); + trace_dump_escape(stream, value3); + trace_dump_write(stream, "\'>"); +} + + +static INLINE void +trace_dump_tag_end(struct trace_stream *stream, + const char *name) +{ + trace_dump_write(stream, ""); +} + + +void trace_dump_trace_begin(struct trace_stream *stream, + unsigned version) +{ + trace_dump_write(stream, "\n"); + trace_dump_write(stream, "\n"); + trace_dump_writef(stream, "\n", version); +} + + +void trace_dump_trace_end(struct trace_stream *stream) +{ + trace_dump_write(stream, "\n"); +} + +void trace_dump_call_begin(struct trace_stream *stream, + const char *klass, const char *method) +{ + trace_dump_indent(stream, 1); + trace_dump_tag_begin2(stream, "call", "class", klass, "method", method); + trace_dump_newline(stream); +} + +void trace_dump_call_end(struct trace_stream *stream) +{ + trace_dump_indent(stream, 1); + trace_dump_tag_end(stream, "call"); + trace_dump_newline(stream); +} + +void trace_dump_arg_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_indent(stream, 2); + trace_dump_tag_begin1(stream, "arg", "name", name); +} + +void trace_dump_arg_end(struct trace_stream *stream) +{ + trace_dump_tag_end(stream, "arg"); + trace_dump_newline(stream); +} + +void trace_dump_ret_begin(struct trace_stream *stream) +{ + trace_dump_indent(stream, 2); + trace_dump_tag_begin(stream, "ret"); +} + +void trace_dump_ret_end(struct trace_stream *stream) +{ + trace_dump_tag_end(stream, "ret"); + trace_dump_newline(stream); +} + +void trace_dump_bool(struct trace_stream *stream, + int value) +{ + trace_dump_writef(stream, "%c", value ? '1' : '0'); +} + +void trace_dump_int(struct trace_stream *stream, + long int value) +{ + trace_dump_writef(stream, "%li", value); +} + +void trace_dump_uint(struct trace_stream *stream, + long unsigned value) +{ + trace_dump_writef(stream, "%lu", value); +} + +void trace_dump_float(struct trace_stream *stream, + double value) +{ + trace_dump_writef(stream, "%g", value); +} + +void trace_dump_string(struct trace_stream *stream, + const char *str) +{ + trace_dump_write(stream, ""); + trace_dump_escape(stream, str); + trace_dump_write(stream, ""); +} + +void trace_dump_array_begin(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_array_end(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_elem_begin(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_elem_end(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_struct_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_writef(stream, "", name); +} + +void trace_dump_struct_end(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_member_begin(struct trace_stream *stream, + const char *name) +{ + trace_dump_writef(stream, "", name); +} + +void trace_dump_member_end(struct trace_stream *stream) +{ + trace_dump_write(stream, ""); +} + +void trace_dump_ptr(struct trace_stream *stream, + const void *value) +{ + trace_dump_writef(stream, "%p", value); +} diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h new file mode 100644 index 0000000000..f086486591 --- /dev/null +++ b/src/gallium/drivers/trace/tr_dump.h @@ -0,0 +1,102 @@ +/************************************************************************** + * + * 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 streams (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Trace data dumping primitives. + */ + +#ifndef TR_DUMP_H +#define TR_DUMP_H + + +struct trace_stream; + + +void trace_dump_trace_begin(struct trace_stream *stream, unsigned version); +void trace_dump_trace_end(struct trace_stream *stream); +void trace_dump_call_begin(struct trace_stream *stream, const char *klass, const char *method); +void trace_dump_call_end(struct trace_stream *stream); +void trace_dump_arg_begin(struct trace_stream *stream, const char *name); +void trace_dump_arg_end(struct trace_stream *stream); +void trace_dump_ret_begin(struct trace_stream *stream); +void trace_dump_ret_end(struct trace_stream *stream); +void trace_dump_bool(struct trace_stream *stream, int value); +void trace_dump_int(struct trace_stream *stream, long int value); +void trace_dump_uint(struct trace_stream *stream, long unsigned value); +void trace_dump_float(struct trace_stream *stream, double value); +void trace_dump_string(struct trace_stream *stream, const char *str); +void trace_dump_array_begin(struct trace_stream *stream); +void trace_dump_array_end(struct trace_stream *stream); +void trace_dump_elem_begin(struct trace_stream *stream); +void trace_dump_elem_end(struct trace_stream *stream); +void trace_dump_struct_begin(struct trace_stream *stream, const char *name); +void trace_dump_struct_end(struct trace_stream *stream); +void trace_dump_member_begin(struct trace_stream *stream, const char *name); +void trace_dump_member_end(struct trace_stream *stream); +void trace_dump_ptr(struct trace_stream *stream, const void *value); + + +/* + * Code saving macros. + */ + +#define trace_dump_arg(_stream, _type, _arg) \ + do { \ + trace_dump_arg_begin(_stream, #_arg); \ + trace_dump_##_type(_stream, _arg); \ + trace_dump_arg_end(_stream); \ + } while(0) + +#define trace_dump_ret(_stream, _type, _arg) \ + do { \ + trace_dump_ret_begin(_stream); \ + trace_dump_##_type(_stream, _arg); \ + trace_dump_ret_end(_stream); \ + } while(0) + +#define trace_dump_array(_stream, _type, _obj, _size) \ + do { \ + unsigned long idx; \ + trace_dump_array_begin(_stream); \ + for(idx = 0; idx < _size; ++idx) { \ + trace_dump_elem_begin(_stream); \ + trace_dump_##_type(_stream, _obj[idx]); \ + trace_dump_elem_end(_stream); \ + } \ + trace_dump_array_end(_stream); \ + } while(0) + +#define trace_dump_member(_stream, _type, _obj, _member) \ + do { \ + trace_dump_member_begin(_stream, #_member); \ + trace_dump_##_type(_stream, _obj->_member); \ + trace_dump_member_end(_stream); \ + } while(0) + + +#endif /* TR_DUMP_H */ diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c new file mode 100644 index 0000000000..20a2026e1d --- /dev/null +++ b/src/gallium/drivers/trace/tr_screen.c @@ -0,0 +1,385 @@ +/************************************************************************** + * + * 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 "pipe/p_util.h" + +#include "tr_stream.h" +#include "tr_dump.h" +#include "tr_state.h" +#include "tr_screen.h" + + +static const char * +trace_screen_get_name(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_name"); + + trace_dump_arg(stream, ptr, screen); + + result = screen->get_name(screen); + + trace_dump_ret(stream, string, result); + + trace_dump_call_end(stream); + + return result; +} + + +static const char * +trace_screen_get_vendor(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + const char *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_vendor"); + + trace_dump_arg(stream, ptr, screen); + + result = screen->get_vendor(screen); + + trace_dump_ret(stream, string, result); + + trace_dump_call_end(stream); + + return result; +} + + +static int +trace_screen_get_param(struct pipe_screen *_screen, + int param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + int result; + + trace_dump_call_begin(stream, "pipe_screen", "get_param"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, int, param); + + result = screen->get_param(screen, param); + + trace_dump_ret(stream, int, result); + + trace_dump_call_end(stream); + + return result; +} + + +static float +trace_screen_get_paramf(struct pipe_screen *_screen, + int param) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + float result; + + trace_dump_call_begin(stream, "pipe_screen", "get_paramf"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, int, param); + + result = screen->get_paramf(screen, param); + + trace_dump_ret(stream, float, result); + + trace_dump_call_end(stream); + + return result; +} + + +static boolean +trace_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + boolean result; + + trace_dump_call_begin(stream, "pipe_screen", "is_format_supported"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, int, format); + trace_dump_arg(stream, int, target); + trace_dump_arg(stream, uint, tex_usage); + trace_dump_arg(stream, uint, geom_flags); + + result = screen->is_format_supported(screen, format, target, tex_usage, geom_flags); + + trace_dump_ret(stream, bool, result); + + trace_dump_call_end(stream); + + return result; +} + + +static struct pipe_texture * +trace_screen_texture_create(struct pipe_screen *_screen, + const struct pipe_texture *templat) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_texture *result; + + trace_dump_call_begin(stream, "pipe_screen", "texture_create"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, template, templat); + + result = screen->texture_create(screen, templat); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static struct pipe_texture * +trace_screen_texture_blanket(struct pipe_screen *_screen, + const struct pipe_texture *templat, + const unsigned *ppitch, + struct pipe_buffer *buffer) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + unsigned pitch = *ppitch; + struct pipe_texture *result; + + trace_dump_call_begin(stream, "pipe_screen", "texture_blanket"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, template, templat); + trace_dump_arg(stream, uint, pitch); + trace_dump_arg(stream, ptr, buffer); + + result = screen->texture_blanket(screen, templat, ppitch, buffer); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_texture_release(struct pipe_screen *_screen, + struct pipe_texture **ptexture) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_texture *texture = *ptexture; + + trace_dump_call_begin(stream, "pipe_screen", "texture_release"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, texture); + + screen->texture_release(screen, ptexture); + + trace_dump_call_end(stream); +} + +static struct pipe_surface * +trace_screen_get_tex_surface(struct pipe_screen *_screen, + struct pipe_texture *texture, + unsigned face, unsigned level, + unsigned zslice, + unsigned usage) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *result; + + trace_dump_call_begin(stream, "pipe_screen", "get_tex_surface"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, texture); + trace_dump_arg(stream, uint, face); + trace_dump_arg(stream, uint, level); + trace_dump_arg(stream, uint, zslice); + trace_dump_arg(stream, uint, usage); + + result = screen->get_tex_surface(screen, texture, face, level, zslice, usage); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_tex_surface_release(struct pipe_screen *_screen, + struct pipe_surface **psurface) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *surface = *psurface; + + trace_dump_call_begin(stream, "pipe_screen", "tex_surface_release"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + + screen->tex_surface_release(screen, psurface); + + trace_dump_call_end(stream); +} + + +static void * +trace_screen_surface_map(struct pipe_screen *_screen, + struct pipe_surface *surface, + unsigned flags) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + struct pipe_surface *result; + + trace_dump_call_begin(stream, "pipe_screen", "surface_map"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + trace_dump_arg(stream, uint, flags); + + result = screen->surface_map(screen, surface, flags); + + trace_dump_ret(stream, ptr, result); + + trace_dump_call_end(stream); + + return result; +} + + +static void +trace_screen_surface_unmap(struct pipe_screen *_screen, + struct pipe_surface *surface) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin(stream, "pipe_screen", "surface_unmap"); + + trace_dump_arg(stream, ptr, screen); + trace_dump_arg(stream, ptr, surface); + + screen->surface_unmap(screen, surface); + + trace_dump_call_end(stream); +} + + +static void +trace_screen_destroy(struct pipe_screen *_screen) +{ + struct trace_screen *tr_scr = trace_screen(_screen); + struct trace_stream *stream = tr_scr->stream; + struct pipe_screen *screen = tr_scr->screen; + + trace_dump_call_begin(stream, "pipe_screen", "destroy"); + + trace_dump_arg(stream, ptr, screen); + + screen->destroy(screen); + + trace_dump_call_end(stream); + + trace_dump_trace_end(stream); + + trace_stream_close(tr_scr->stream); + + FREE(tr_scr); +} + + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen) +{ + struct trace_screen *tr_scr; + + if(!debug_get_bool_option("GALLIUM_TRACE", FALSE)) + return screen; + + tr_scr = CALLOC_STRUCT(trace_screen); + if(!tr_scr) + return NULL; + + tr_scr->base.winsys = screen->winsys; + tr_scr->base.destroy = trace_screen_destroy; + tr_scr->base.get_name = trace_screen_get_name; + tr_scr->base.get_vendor = trace_screen_get_vendor; + tr_scr->base.get_param = trace_screen_get_param; + tr_scr->base.get_paramf = trace_screen_get_paramf; + tr_scr->base.is_format_supported = trace_screen_is_format_supported; + tr_scr->base.texture_create = trace_screen_texture_create; + tr_scr->base.texture_blanket = trace_screen_texture_blanket; + tr_scr->base.texture_release = trace_screen_texture_release; + tr_scr->base.get_tex_surface = trace_screen_get_tex_surface; + tr_scr->base.tex_surface_release = trace_screen_tex_surface_release; + tr_scr->base.surface_map = trace_screen_surface_map; + tr_scr->base.surface_unmap = trace_screen_surface_unmap; + + tr_scr->screen = screen; + + tr_scr->stream = trace_stream_create("gallium", "trace"); + if(!tr_scr->stream) + return NULL; + + trace_dump_trace_begin(tr_scr->stream, 0); + + return &tr_scr->base; +} diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h new file mode 100644 index 0000000000..5d7d667f71 --- /dev/null +++ b/src/gallium/drivers/trace/tr_screen.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef TR_SCREEN_H_ +#define TR_SCREEN_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_debug.h" +#include "pipe/p_screen.h" + + +struct trace_stream; + + +struct trace_screen +{ + struct pipe_screen base; + + struct pipe_screen *screen; + + struct trace_stream *stream; + + unsigned event_no; +}; + + +static INLINE struct trace_screen * +trace_screen(struct pipe_screen *screen) +{ + assert(screen); + return (struct trace_screen *)screen; +} + + + +struct pipe_screen * +trace_screen_create(struct pipe_screen *screen); + + +#endif /* TR_SCREEN_H_ */ diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c new file mode 100644 index 0000000000..1e0e87f7fd --- /dev/null +++ b/src/gallium/drivers/trace/tr_state.c @@ -0,0 +1,72 @@ +/************************************************************************** + * + * 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 "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "tr_dump.h" +#include "tr_state.h" + + +void trace_dump_block(struct trace_stream *stream, + const struct pipe_format_block *block) +{ + trace_dump_struct_begin(stream, "pipe_format_block"); + trace_dump_member(stream, uint, block, size); + trace_dump_member(stream, uint, block, width); + trace_dump_member(stream, uint, block, height); + trace_dump_struct_end(stream); +} + + +void trace_dump_template(struct trace_stream *stream, + const struct pipe_texture *templat) +{ + trace_dump_struct_begin(stream, "pipe_texture"); + + trace_dump_member(stream, int, templat, target); + trace_dump_member(stream, int, templat, format); + + trace_dump_member_begin(stream, "width"); + trace_dump_array(stream, uint, templat->width, 1); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "height"); + trace_dump_array(stream, uint, templat->height, 1); + trace_dump_member_end(stream); + + trace_dump_member_begin(stream, "block"); + trace_dump_block(stream, &templat->block); + trace_dump_member_end(stream); + + trace_dump_member(stream, uint, templat, last_level); + trace_dump_member(stream, uint, templat, tex_usage); + + trace_dump_struct_end(stream); +} + diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h new file mode 100644 index 0000000000..e52524ee90 --- /dev/null +++ b/src/gallium/drivers/trace/tr_state.h @@ -0,0 +1,44 @@ +/************************************************************************** + * + * 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 streams (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 TR_STATE_H +#define TR_STATE_H + + +struct trace_stream; + +struct pipe_format_block; +struct pipe_texture; + +void trace_dump_block(struct trace_stream *stream, + const struct pipe_format_block *block); + +void trace_dump_template(struct trace_stream *stream, + const struct pipe_texture *templat); + + +#endif /* TR_STATE_H */ diff --git a/src/gallium/drivers/trace/tr_stream.c b/src/gallium/drivers/trace/tr_stream.c new file mode 100644 index 0000000000..14cc257e15 --- /dev/null +++ b/src/gallium/drivers/trace/tr_stream.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * 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 "pipe/p_config.h" + +#if defined(PIPE_OS_LINUX) +#include +#else +#error Unsupported platform +#endif + +#include "pipe/p_util.h" + +#include "tr_stream.h" + + +struct trace_stream +{ +#if defined(PIPE_OS_LINUX) + FILE *file; +#endif +}; + + +struct trace_stream * +trace_stream_create(const char *name, const char *ext) +{ + struct trace_stream *stream; + static unsigned file_no = 0; + char filename[1024]; + + stream = CALLOC_STRUCT(trace_stream); + if(!stream) + goto error1; + + snprintf(filename, sizeof(filename), "%s.%u.%s", name, file_no, ext); + +#if defined(PIPE_OS_LINUX) + stream->file = fopen(filename, "w"); + if(!stream->file) + goto error2; +#endif + + return stream; + +error2: + FREE(stream); +error1: + return NULL; +} + + +boolean +trace_stream_write(struct trace_stream *stream, const void *data, size_t size) +{ + if(!stream) + return FALSE; + +#if defined(PIPE_OS_LINUX) + return fwrite(data, size, 1, stream->file) == size ? TRUE : FALSE; +#endif +} + + +void +trace_stream_close(struct trace_stream *stream) +{ + if(!stream) + return; + +#if defined(PIPE_OS_LINUX) + fclose(stream->file); +#endif + + FREE(stream); +} diff --git a/src/gallium/drivers/trace/tr_stream.h b/src/gallium/drivers/trace/tr_stream.h new file mode 100644 index 0000000000..d50fed2691 --- /dev/null +++ b/src/gallium/drivers/trace/tr_stream.h @@ -0,0 +1,52 @@ +/************************************************************************** + * + * 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 streams (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Cross-platform sequential access stream abstraction. + */ + +#ifndef TR_STREAM_H +#define TR_STREAM_H + + +#include "pipe/p_compiler.h" + +struct trace_stream; + + +struct trace_stream * +trace_stream_create(const char *name, const char *ext); + +boolean +trace_stream_write(struct trace_stream *stream, const void *data, size_t size); + +void +trace_stream_close(struct trace_stream *stream); + + +#endif /* TR_STREAM_H */ -- cgit v1.2.3 From f52db6cd4436ec8b14e592f4b2b99f5840bdf47a Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Thu, 21 Aug 2008 01:41:20 +0100 Subject: scons: Build the trace pipe driver by default. --- SConstruct | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index ee96bc5ab2..cd5b228b3b 100644 --- a/SConstruct +++ b/SConstruct @@ -32,10 +32,10 @@ import common default_statetrackers = 'mesa' if common.default_platform in ('linux', 'freebsd', 'darwin'): - default_drivers = 'softpipe,failover,i915simple,i965simple' + default_drivers = 'softpipe,failover,i915simple,i965simple,trace' default_winsys = 'xlib' elif common.default_platform in ('winddk',): - default_drivers = 'softpipe,i915simple' + default_drivers = 'softpipe,i915simple,trace' default_winsys = 'all' else: default_drivers = 'all' -- cgit v1.2.3 From 3c819926768e3879c8deaedfca964cc52ed1a7c5 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 29 Aug 2008 11:30:32 -0600 Subject: Added command line option for Scons to select which version of MSVS to use. Versions 7.1, 8.0 and 9.0 are allowed. Usage is scons MSVS_VERSION=8.0. --- SConstruct | 2 ++ 1 file changed, 2 insertions(+) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index cd5b228b3b..c1dc624651 100644 --- a/SConstruct +++ b/SConstruct @@ -50,6 +50,8 @@ opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'intel', 'gdi'])) +opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) + env = Environment( options = opts, tools = ['gallium'], -- cgit v1.2.3 From 6b69e3c71741d99a54c6f4dcb605a3c241239aeb Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 23 Oct 2008 10:28:48 +0200 Subject: scons: ppc support. --- SConstruct | 2 ++ common.py | 3 ++- scons/gallium.py | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/rtasm/SConscript | 1 + src/gallium/auxiliary/tgsi/SConscript | 1 + src/mesa/SConscript | 4 ++++ 7 files changed, 12 insertions(+), 1 deletion(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index c1dc624651..8c96817dae 100644 --- a/SConstruct +++ b/SConstruct @@ -70,12 +70,14 @@ platform = env['platform'] # derived options x86 = machine == 'x86' +ppc = machine == 'ppc' gcc = platform in ('linux', 'freebsd', 'darwin') msvc = platform in ('windows', 'winddk') Export([ 'debug', 'x86', + 'ppc', 'dri', 'llvm', 'platform', diff --git a/common.py b/common.py index dd64e0f434..cc2582f1a4 100644 --- a/common.py +++ b/common.py @@ -24,6 +24,7 @@ _machine_map = { 'i486': 'x86', 'i586': 'x86', 'i686': 'x86', + 'ppc' : 'ppc', 'x86_64': 'x86_64', } if 'PROCESSOR_ARCHITECTURE' in os.environ: @@ -56,7 +57,7 @@ def AddOptions(opts): opts.Add(BoolOption('profile', 'profile build', 'no')) #opts.Add(BoolOption('quiet', 'quiet command lines', 'no')) opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, - allowed_values=('generic', 'x86', 'x86_64'))) + allowed_values=('generic', 'ppc', 'x86', 'x86_64'))) opts.Add(EnumOption('platform', 'target platform', default_platform, allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince'))) opts.Add(BoolOption('llvm', 'use LLVM', 'no')) diff --git a/scons/gallium.py b/scons/gallium.py index 3631607e66..2a42bdf2bb 100644 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -175,6 +175,7 @@ def generate(env): machine = env['machine'] platform = env['platform'] x86 = env['machine'] == 'x86' + ppc = env['machine'] == 'ppc' gcc = env['platform'] in ('linux', 'freebsd', 'darwin') msvc = env['platform'] in ('windows', 'winddk', 'wince') diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 544a04918b..5f05aa324a 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -38,6 +38,7 @@ draw = env.ConvenienceLibrary( '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' ]) diff --git a/src/gallium/auxiliary/rtasm/SConscript b/src/gallium/auxiliary/rtasm/SConscript index 8ea25922aa..eb48368acc 100644 --- a/src/gallium/auxiliary/rtasm/SConscript +++ b/src/gallium/auxiliary/rtasm/SConscript @@ -6,6 +6,7 @@ rtasm = env.ConvenienceLibrary( 'rtasm_cpu.c', 'rtasm_execmem.c', 'rtasm_x86sse.c', + 'rtasm_ppc.c', 'rtasm_ppc_spe.c', ]) diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript index 45bf3f6d57..8200cce42f 100644 --- a/src/gallium/auxiliary/tgsi/SConscript +++ b/src/gallium/auxiliary/tgsi/SConscript @@ -12,6 +12,7 @@ tgsi = env.ConvenienceLibrary( 'tgsi_parse.c', 'tgsi_sanity.c', 'tgsi_scan.c', + 'tgsi_ppc.c', 'tgsi_sse2.c', 'tgsi_text.c', 'tgsi_transform.c', diff --git a/src/mesa/SConscript b/src/mesa/SConscript index af8dfcb493..89b98b37ab 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -283,6 +283,10 @@ if env['platform'] != 'winddk': 'x86-64/glapi_x86-64.S' ] elif gcc and env['machine'] == 'ppc': + env.Append(CPPDEFINES = [ + 'USE_PPC_ASM', + 'USE_VMX_ASM', + ]) mesa_sources += [ 'ppc/common_ppc.c', ] -- cgit v1.2.3 From 359bbe7432babb328a313756b9d1e46e187914b8 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 12 Jan 2009 12:37:13 +0100 Subject: gallivm: Explicitly specify the LLVM components we need. --- SConstruct | 2 +- configs/linux-llvm | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 8c96817dae..baa0f9069b 100644 --- a/SConstruct +++ b/SConstruct @@ -133,7 +133,7 @@ if dri: # LLVM if llvm: # See also http://www.scons.org/wiki/UsingPkgConfig - env.ParseConfig('llvm-config --cflags --ldflags --libs') + env.ParseConfig('llvm-config --cflags --ldflags --libs backend bitreader engine ipo') env.Append(CPPDEFINES = ['MESA_LLVM']) # Force C++ linkage env['LINK'] = env['CXX'] diff --git a/configs/linux-llvm b/configs/linux-llvm index 489cfd0546..a9d740574c 100644 --- a/configs/linux-llvm +++ b/configs/linux-llvm @@ -22,9 +22,9 @@ endif ifeq ($(MESA_LLVM),1) # LLVM_CFLAGS=`llvm-config --cflags` - LLVM_CXXFLAGS=`llvm-config --cxxflags` -Wno-long-long - LLVM_LDFLAGS=`llvm-config --ldflags` - LLVM_LIBS=`llvm-config --libs` + LLVM_CXXFLAGS=`llvm-config --cxxflags backend bitreader engine ipo` -Wno-long-long + LLVM_LDFLAGS=`llvm-config --ldflags backend bitreader engine ipo` + LLVM_LIBS=`llvm-config --libs backend bitreader engine ipo` MKLIB_OPTIONS=-cplusplus else LLVM_CFLAGS= -- cgit v1.2.3 From 9bf83fb0162b5ce95fc10ca1a38e6b4a62f9690f Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 24 Jan 2009 15:56:28 +0000 Subject: scons: Build the progs into seperate dirs as well. --- SConstruct | 2 +- progs/SConstruct | 1 + scons/generic.py | 9 ++++----- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index baa0f9069b..88cdffa504 100644 --- a/SConstruct +++ b/SConstruct @@ -162,6 +162,6 @@ Export('env') SConscript( 'src/SConscript', - build_dir = env['build'], + variant_dir = env['build'], duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html ) diff --git a/progs/SConstruct b/progs/SConstruct index bce48f72ff..4d268cc6d7 100644 --- a/progs/SConstruct +++ b/progs/SConstruct @@ -60,5 +60,6 @@ Export('env') SConscript( 'SConscript', + build_dir = env['build'], duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html ) diff --git a/scons/generic.py b/scons/generic.py index 7ded920790..df7ef42402 100644 --- a/scons/generic.py +++ b/scons/generic.py @@ -251,7 +251,7 @@ def generate(env): # Put build output in a separate dir, which depends on the current # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample try: - env['variant_dir'] = ARGUMENTS['variant_dir'] + env['build'] = ARGUMENTS['build'] except KeyError: build_topdir = 'build' build_subdir = env['platform'] @@ -261,11 +261,10 @@ def generate(env): build_subdir += "-debug" if env['profile']: build_subdir += "-profile" - env['variant_dir'] = os.path.join(build_topdir, build_subdir) + env['build'] = os.path.join(build_topdir, build_subdir) # Place the .sconsign file in the build dir too, to avoid issues with # different scons versions building the same source file - #env.VariantDir(env['variant_dir'] - #env.SConsignFile(os.path.join(env['variant_dir'], '.sconsign')) + env.SConsignFile(os.path.join(env['build'], '.sconsign')) # Summary print @@ -274,7 +273,7 @@ def generate(env): print ' toolchain=%s' % env['toolchain'] print ' debug=%s' % ['no', 'yes'][env['debug']] print ' profile=%s' % ['no', 'yes'][env['profile']] - #print ' variant_dir=%s' % env['variant_dir'] + print ' build=%s' % env['build'] print # Load tool chain -- cgit v1.2.3 From e9b08e7373c00306bce398ea8d34f42e54f98c6d Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 9 Jan 2009 21:28:23 -0800 Subject: Make r300 and amd build in scons. --- SConstruct | 4 ++-- src/gallium/drivers/r300/SConscript | 17 +++++++++++++++++ src/gallium/drivers/r300/r300_blit.h | 1 + src/gallium/winsys/drm/amd/SConscript | 29 +++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/gallium/drivers/r300/SConscript create mode 100644 src/gallium/winsys/drm/amd/SConscript (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 88cdffa504..a22b9483da 100644 --- a/SConstruct +++ b/SConstruct @@ -46,9 +46,9 @@ common.AddOptions(opts) opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers, ['mesa', 'python'])) opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, - ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace'])) + ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300'])) opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, - ['xlib', 'intel', 'gdi'])) + ['xlib', 'intel', 'gdi', 'amd'])) opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript new file mode 100644 index 0000000000..18684c3e7f --- /dev/null +++ b/src/gallium/drivers/r300/SConscript @@ -0,0 +1,17 @@ +Import('*') + +env = env.Clone() + +r300 = env.ConvenienceLibrary( + target = 'r300', + source = [ + 'r300_blit.c', + 'r300_clear.c', + 'r300_context.c', + 'r300_screen.c', + 'r300_state.c', + 'r300_surface.c', + ]) + +Export('r300') + diff --git a/src/gallium/drivers/r300/r300_blit.h b/src/gallium/drivers/r300/r300_blit.h index 09cb566b95..740cbcdea5 100644 --- a/src/gallium/drivers/r300/r300_blit.h +++ b/src/gallium/drivers/r300/r300_blit.h @@ -25,6 +25,7 @@ #include "pipe/p_state.h" +#include "r300_context.h" #include "r300_cs.h" /* Forward declarations. */ diff --git a/src/gallium/winsys/drm/amd/SConscript b/src/gallium/winsys/drm/amd/SConscript new file mode 100644 index 0000000000..a4856da23c --- /dev/null +++ b/src/gallium/winsys/drm/amd/SConscript @@ -0,0 +1,29 @@ +Import('*') + +if 'mesa' in env['statetrackers']: + + env = drienv.Clone() + + DRIVER_SOURCES = [ + 'amd_buffer.c', + 'amd_context.c', + 'amd_screen.c', + 'amd_winsys_softpipe.c', + ] + + sources = \ + COMMON_GALLIUM_SOURCES + \ + DRIVER_SOURCES + + drivers = [ + softpipe, + r300 + ] + + # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions + env.SharedLibrary( + target ='amd_dri.so', + source = sources, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], + ) + -- cgit v1.2.3 From 056f847e96aa84c1e7c9ee7ce60f4d7f7603676b Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 18 Feb 2009 17:12:18 +0000 Subject: gallium: Also disable i965simple for scons Please read previous commit for more info. --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index a22b9483da..7f9a222542 100644 --- a/SConstruct +++ b/SConstruct @@ -32,7 +32,7 @@ import common default_statetrackers = 'mesa' if common.default_platform in ('linux', 'freebsd', 'darwin'): - default_drivers = 'softpipe,failover,i915simple,i965simple,trace' + default_drivers = 'softpipe,failover,i915simple,trace' default_winsys = 'xlib' elif common.default_platform in ('winddk',): default_drivers = 'softpipe,i915simple,trace' -- cgit v1.2.3 From 2b6235c9f79d3d1719601d3a92d67e20a578b626 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 9 Mar 2009 17:46:49 +0100 Subject: scons: Also link in additional LLVM components. They don't seem necessary here, but they shouldn't hurt either... --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 7f9a222542..7e7f51516e 100644 --- a/SConstruct +++ b/SConstruct @@ -133,7 +133,7 @@ if dri: # LLVM if llvm: # See also http://www.scons.org/wiki/UsingPkgConfig - env.ParseConfig('llvm-config --cflags --ldflags --libs backend bitreader engine ipo') + env.ParseConfig('llvm-config --cflags --ldflags --libs backend bitreader engine instrumentation interpreter ipo') env.Append(CPPDEFINES = ['MESA_LLVM']) # Force C++ linkage env['LINK'] = env['CXX'] -- cgit v1.2.3 From b7ffe1e8763efdf042e2d5eb33ce4f3d5d365121 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Sat, 4 Apr 2009 00:34:10 -0700 Subject: Add scons build support for radeon/r300. --- SConstruct | 2 +- src/gallium/drivers/r300/SConscript | 28 ++++++++++++++++++--------- src/gallium/winsys/drm/SConscript | 5 +++++ src/gallium/winsys/drm/radeon/SConscript | 28 +++------------------------ src/gallium/winsys/drm/radeon/core/SConscript | 17 ++++++++++++++++ src/gallium/winsys/drm/radeon/dri2/SConscript | 14 ++++++++++++++ 6 files changed, 59 insertions(+), 35 deletions(-) create mode 100644 src/gallium/winsys/drm/radeon/core/SConscript create mode 100644 src/gallium/winsys/drm/radeon/dri2/SConscript (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 7e7f51516e..1e5fd71adc 100644 --- a/SConstruct +++ b/SConstruct @@ -48,7 +48,7 @@ opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetra opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300'])) opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, - ['xlib', 'intel', 'gdi', 'amd'])) + ['xlib', 'intel', 'gdi', 'radeon'])) opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 18684c3e7f..c914bc7c40 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -3,15 +3,25 @@ Import('*') env = env.Clone() r300 = env.ConvenienceLibrary( - target = 'r300', - source = [ - 'r300_blit.c', - 'r300_clear.c', - 'r300_context.c', - 'r300_screen.c', - 'r300_state.c', - 'r300_surface.c', - ]) + target = 'r300', + source = [ + 'r300_chipset.c', + 'r300_clear.c', + 'r300_context.c', + 'r300_debug.c', + 'r300_emit.c', + 'r300_flush.c', + 'r300_query.c', + 'r300_screen.c', + 'r300_state.c', + 'r300_state_derived.c', + 'r300_state_invariant.c', + 'r300_state_shader.c', + 'r300_state_tcl.c', + 'r300_surface.c', + 'r300_swtcl_emit.c', + 'r300_texture.c', + ]) Export('r300') diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript index aef5210a32..a9e9f2682a 100644 --- a/src/gallium/winsys/drm/SConscript +++ b/src/gallium/winsys/drm/SConscript @@ -52,3 +52,8 @@ if env['dri']: SConscript([ 'intel/SConscript', ]) + + if 'radeon' in env['winsys']: + SConscript([ + 'radeon/SConscript', + ]) diff --git a/src/gallium/winsys/drm/radeon/SConscript b/src/gallium/winsys/drm/radeon/SConscript index 2435211a32..8f99055b2f 100644 --- a/src/gallium/winsys/drm/radeon/SConscript +++ b/src/gallium/winsys/drm/radeon/SConscript @@ -1,29 +1,7 @@ Import('*') -if 'mesa' in env['statetrackers']: - - env = drienv.Clone() - - DRIVER_SOURCES = [ - 'radeon_buffer.c', - 'radeon_context.c', - 'radeon_screen.c', - 'radeon_winsys_softpipe.c', - ] +SConscript(['core/SConscript',]) - sources = \ - COMMON_GALLIUM_SOURCES + \ - DRIVER_SOURCES - - drivers = [ - softpipe, - r300 - ] - - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.SharedLibrary( - target ='radeon_dri.so', - source = sources, - LIBS = drivers + mesa + auxiliaries + env['LIBS'], - ) +if 'mesa' in env['statetrackers']: + SConscript(['dri2/SConscript']) diff --git a/src/gallium/winsys/drm/radeon/core/SConscript b/src/gallium/winsys/drm/radeon/core/SConscript new file mode 100644 index 0000000000..578174e32b --- /dev/null +++ b/src/gallium/winsys/drm/radeon/core/SConscript @@ -0,0 +1,17 @@ +Import('*') + +env = drienv.Clone() + +radeon_sources = [ + 'radeon_buffer.c', + 'radeon_drm.c', + 'radeon_r300.c', + 'radeon_winsys_softpipe.c', +] + +env.Append(CPPPATH = '#/src/gallium/drivers/r300') + +env.ConvenienceLibrary( + target ='radeonwinsys', + source = radeon_sources, +) diff --git a/src/gallium/winsys/drm/radeon/dri2/SConscript b/src/gallium/winsys/drm/radeon/dri2/SConscript new file mode 100644 index 0000000000..f2cdee97d9 --- /dev/null +++ b/src/gallium/winsys/drm/radeon/dri2/SConscript @@ -0,0 +1,14 @@ +Import('*') + +env = drienv.Clone() + +drivers = [ + softpipe, + r300 +] + +env.SharedLibrary( + target ='radeon_dri.so', + source = COMMON_GALLIUM_SOURCES, + LIBS = drivers + mesa + auxiliaries + env['LIBS'], +) -- cgit v1.2.3 From e9fb90ab8889136f788a3d9dc395b0f4d46cfdcc Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 1 May 2009 16:12:17 +0100 Subject: scons: Don't use deprecated Options. --- SConstruct | 10 +++++----- common.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 1e5fd71adc..89144f7579 100644 --- a/SConstruct +++ b/SConstruct @@ -41,16 +41,16 @@ else: default_drivers = 'all' default_winsys = 'all' -opts = Options('config.py') +opts = Variables('config.py') common.AddOptions(opts) -opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers, +opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers, ['mesa', 'python'])) -opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, +opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers, ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300'])) -opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, +opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'intel', 'gdi', 'radeon'])) -opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) +opts.Add(EnumVariable('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) env = Environment( options = opts, diff --git a/common.py b/common.py index f1c6372abd..e57429eb75 100644 --- a/common.py +++ b/common.py @@ -46,13 +46,13 @@ else: def AddOptions(opts): try: - from SCons.Options.BoolOption import BoolOption - except ImportError: from SCons.Variables.BoolVariable import BoolVariable as BoolOption - try: - from SCons.Options.EnumOption import EnumOption except ImportError: + from SCons.Options.BoolOption import BoolOption + try: from SCons.Variables.EnumVariable import EnumVariable as EnumOption + except ImportError: + from SCons.Options.EnumOption import EnumOption opts.Add(BoolOption('debug', 'debug build', 'no')) opts.Add(BoolOption('profile', 'profile build', 'no')) #opts.Add(BoolOption('quiet', 'quiet command lines', 'no')) -- cgit v1.2.3 From d60b2c68552a2729dfdb33c2bac4822453cf8ae2 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Wed, 24 Jun 2009 02:42:41 +0200 Subject: identity: Add new identity driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver does no transformation of the gallium calls going to the real driver, like the identity matrix. It is intended to be the basis for transforming and/or debug drivers like trace and rbug. Authors of this patch are: Michal Krol, orignal heavy lifting. José Fonesca, object wrapping code stolen from trace. Jakob Bornecrantz, put it all toghether and renamed a stuff. --- SConstruct | 6 +- configs/default | 2 +- configure.ac | 2 +- src/gallium/drivers/identity/Makefile | 11 + src/gallium/drivers/identity/SConscript | 13 + src/gallium/drivers/identity/id_context.c | 719 ++++++++++++++++++++++++++++++ src/gallium/drivers/identity/id_context.h | 48 ++ src/gallium/drivers/identity/id_objects.c | 182 ++++++++ src/gallium/drivers/identity/id_objects.h | 169 +++++++ src/gallium/drivers/identity/id_public.h | 40 ++ src/gallium/drivers/identity/id_screen.c | 481 ++++++++++++++++++++ src/gallium/drivers/identity/id_screen.h | 48 ++ 12 files changed, 1716 insertions(+), 5 deletions(-) create mode 100644 src/gallium/drivers/identity/Makefile create mode 100644 src/gallium/drivers/identity/SConscript create mode 100644 src/gallium/drivers/identity/id_context.c create mode 100644 src/gallium/drivers/identity/id_context.h create mode 100644 src/gallium/drivers/identity/id_objects.c create mode 100644 src/gallium/drivers/identity/id_objects.h create mode 100644 src/gallium/drivers/identity/id_public.h create mode 100644 src/gallium/drivers/identity/id_screen.c create mode 100644 src/gallium/drivers/identity/id_screen.h (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 89144f7579..4a0fb94deb 100644 --- a/SConstruct +++ b/SConstruct @@ -32,10 +32,10 @@ import common default_statetrackers = 'mesa' if common.default_platform in ('linux', 'freebsd', 'darwin'): - default_drivers = 'softpipe,failover,i915simple,trace' + default_drivers = 'softpipe,failover,i915simple,trace,identity' default_winsys = 'xlib' elif common.default_platform in ('winddk',): - default_drivers = 'softpipe,i915simple,trace' + default_drivers = 'softpipe,i915simple,trace,identity' default_winsys = 'all' else: default_drivers = 'all' @@ -46,7 +46,7 @@ common.AddOptions(opts) opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers, ['mesa', 'python'])) opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers, - ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300'])) + ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity'])) opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'intel', 'gdi', 'radeon'])) diff --git a/configs/default b/configs/default index dc28be37dd..a8996702d7 100644 --- a/configs/default +++ b/configs/default @@ -95,7 +95,7 @@ EGL_DRIVERS_DIRS = demo GALLIUM_DIRS = auxiliary drivers state_trackers GALLIUM_AUXILIARY_DIRS = rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVERS_DIRS = softpipe i915simple failover trace +GALLIUM_DRIVERS_DIRS = softpipe i915simple failover trace identity GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVERS_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib egl_xlib GALLIUM_WINSYS_DRM_DIRS = diff --git a/configure.ac b/configure.ac index f34a4740b3..6db237c793 100644 --- a/configure.ac +++ b/configure.ac @@ -417,7 +417,7 @@ GALLIUM_DIRS="auxiliary drivers state_trackers" GALLIUM_WINSYS_DIRS="" GALLIUM_WINSYS_DRM_DIRS="" GALLIUM_AUXILIARY_DIRS="rbug draw translate cso_cache pipebuffer tgsi sct rtasm util indices" -GALLIUM_DRIVERS_DIRS="softpipe failover trace" +GALLIUM_DRIVERS_DIRS="softpipe failover trace identity" GALLIUM_STATE_TRACKERS_DIRS="" case "$mesa_driver" in diff --git a/src/gallium/drivers/identity/Makefile b/src/gallium/drivers/identity/Makefile new file mode 100644 index 0000000000..74692d9761 --- /dev/null +++ b/src/gallium/drivers/identity/Makefile @@ -0,0 +1,11 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = identity + +C_SOURCES = \ + id_objects.c \ + id_context.c \ + id_screen.c + +include ../../Makefile.template diff --git a/src/gallium/drivers/identity/SConscript b/src/gallium/drivers/identity/SConscript new file mode 100644 index 0000000000..7f079dd0a8 --- /dev/null +++ b/src/gallium/drivers/identity/SConscript @@ -0,0 +1,13 @@ +Import('*') + +env = env.Clone() + +identity = env.ConvenienceLibrary( + target = 'identity', + source = [ + 'id_screen.c', + 'id_context.c', + 'id_objects.c', + ]) + +Export('identity') diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c new file mode 100644 index 0000000000..a500ec6045 --- /dev/null +++ b/src/gallium/drivers/identity/id_context.c @@ -0,0 +1,719 @@ +/************************************************************************** + * + * 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_context.h" +#include "util/u_memory.h" + +#include "id_public.h" +#include "id_context.h" +#include "id_objects.h" + + +static void +identity_destroy(struct pipe_context *_pipe) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->destroy(pipe); + + free(id_pipe); +} + +static void +identity_set_edgeflags(struct pipe_context *_pipe, + const unsigned *bitfield) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_edgeflags(pipe, + bitfield); +} + +static boolean +identity_draw_arrays(struct pipe_context *_pipe, + unsigned prim, + unsigned start, + unsigned count) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->draw_arrays(pipe, + prim, + start, + count); +} + +static boolean +identity_draw_elements(struct pipe_context *_pipe, + struct pipe_buffer *_indexBuffer, + unsigned indexSize, + unsigned prim, + unsigned start, + unsigned count) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_buffer *id_buffer = identity_buffer(_indexBuffer); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_buffer *indexBuffer = id_buffer->buffer; + + return pipe->draw_elements(pipe, + indexBuffer, + indexSize, + prim, + start, + count); +} + +static boolean +identity_draw_range_elements(struct pipe_context *_pipe, + struct pipe_buffer *_indexBuffer, + unsigned indexSize, + unsigned minIndex, + unsigned maxIndex, + unsigned mode, + unsigned start, + unsigned count) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_buffer *id_buffer = identity_buffer(_indexBuffer); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_buffer *indexBuffer = id_buffer->buffer; + + return pipe->draw_range_elements(pipe, + indexBuffer, + indexSize, + minIndex, + maxIndex, + mode, + start, + count); +} + +static struct pipe_query * +identity_create_query(struct pipe_context *_pipe, + unsigned query_type) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_query(pipe, + query_type); +} + +static void +identity_destroy_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->destroy_query(pipe, + query); +} + +static void +identity_begin_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->begin_query(pipe, + query); +} + +static void +identity_end_query(struct pipe_context *_pipe, + struct pipe_query *query) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->end_query(pipe, + query); +} + +static boolean +identity_get_query_result(struct pipe_context *_pipe, + struct pipe_query *query, + boolean wait, + uint64_t *result) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->get_query_result(pipe, + query, + wait, + result); +} + +static void * +identity_create_blend_state(struct pipe_context *_pipe, + const struct pipe_blend_state *blend) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_blend_state(pipe, + blend); +} + +static void +identity_bind_blend_state(struct pipe_context *_pipe, + void *blend) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_blend_state(pipe, + blend); +} + +static void +identity_delete_blend_state(struct pipe_context *_pipe, + void *blend) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_blend_state(pipe, + blend); +} + +static void * +identity_create_sampler_state(struct pipe_context *_pipe, + const struct pipe_sampler_state *sampler) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_sampler_state(pipe, + sampler); +} + +static void +identity_bind_sampler_states(struct pipe_context *_pipe, + unsigned num, + void **samplers) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_sampler_states(pipe, + num, + samplers); +} + +static void +identity_delete_sampler_state(struct pipe_context *_pipe, + void *sampler) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_sampler_state(pipe, + sampler); +} + +static void * +identity_create_rasterizer_state(struct pipe_context *_pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_rasterizer_state(pipe, + rasterizer); +} + +static void +identity_bind_rasterizer_state(struct pipe_context *_pipe, + void *rasterizer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_rasterizer_state(pipe, + rasterizer); +} + +static void +identity_delete_rasterizer_state(struct pipe_context *_pipe, + void *rasterizer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_rasterizer_state(pipe, + rasterizer); +} + +static void * +identity_create_depth_stencil_alpha_state(struct pipe_context *_pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void +identity_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *depth_stencil_alpha) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void +identity_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, + void *depth_stencil_alpha) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); +} + +static void * +identity_create_fs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *fs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_fs_state(pipe, + fs); +} + +static void +identity_bind_fs_state(struct pipe_context *_pipe, + void *fs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_fs_state(pipe, + fs); +} + +static void +identity_delete_fs_state(struct pipe_context *_pipe, + void *fs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_fs_state(pipe, + fs); +} + +static void * +identity_create_vs_state(struct pipe_context *_pipe, + const struct pipe_shader_state *vs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + return pipe->create_vs_state(pipe, + vs); +} + +static void +identity_bind_vs_state(struct pipe_context *_pipe, + void *vs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->bind_vs_state(pipe, + vs); +} + +static void +identity_delete_vs_state(struct pipe_context *_pipe, + void *vs) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->delete_vs_state(pipe, + vs); +} + +static void +identity_set_blend_color(struct pipe_context *_pipe, + const struct pipe_blend_color *blend_color) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_blend_color(pipe, + blend_color); +} + +static void +identity_set_clip_state(struct pipe_context *_pipe, + const struct pipe_clip_state *clip) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_clip_state(pipe, + clip); +} + +static void +identity_set_constant_buffer(struct pipe_context *_pipe, + uint shader, + uint index, + const struct pipe_constant_buffer *_buffer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_constant_buffer unwrapped_buffer; + struct pipe_constant_buffer *buffer = NULL; + + /* unwrap the input state */ + if (_buffer) { + unwrapped_buffer.buffer = identity_buffer_unwrap(_buffer->buffer); + buffer = &unwrapped_buffer; + } + + pipe->set_constant_buffer(pipe, + shader, + index, + buffer); +} + +static void +identity_set_framebuffer_state(struct pipe_context *_pipe, + const struct pipe_framebuffer_state *_state) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_framebuffer_state unwrapped_state; + struct pipe_framebuffer_state *state = NULL; + unsigned i; + + /* unwrap the input state */ + if (_state) { + memcpy(&unwrapped_state, _state, sizeof(unwrapped_state)); + for(i = 0; i < _state->nr_cbufs; i++) + unwrapped_state.cbufs[i] = identity_surface_unwrap(_state->cbufs[i]); + for (; i < PIPE_MAX_COLOR_BUFS; i++) + unwrapped_state.cbufs[i] = NULL; + unwrapped_state.zsbuf = identity_surface_unwrap(_state->zsbuf); + state = &unwrapped_state; + } + + pipe->set_framebuffer_state(pipe, + state); +} + +static void +identity_set_polygon_stipple(struct pipe_context *_pipe, + const struct pipe_poly_stipple *poly_stipple) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_polygon_stipple(pipe, + poly_stipple); +} + +static void +identity_set_scissor_state(struct pipe_context *_pipe, + const struct pipe_scissor_state *scissor) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_scissor_state(pipe, + scissor); +} + +static void +identity_set_viewport_state(struct pipe_context *_pipe, + const struct pipe_viewport_state *viewport) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_viewport_state(pipe, + viewport); +} + +static void +identity_set_sampler_textures(struct pipe_context *_pipe, + unsigned num_textures, + struct pipe_texture **_textures) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; + struct pipe_texture **textures = NULL; + unsigned i; + + if (_textures) { + for (i = 0; i < num_textures; i++) + unwrapped_textures[i] = identity_texture_unwrap(_textures[i]); + for (; i < PIPE_MAX_SAMPLERS; i++) + unwrapped_textures[i] = NULL; + + textures = unwrapped_textures; + } + + pipe->set_sampler_textures(pipe, + num_textures, + _textures); +} + +static void +identity_set_vertex_buffers(struct pipe_context *_pipe, + unsigned num_buffers, + const struct pipe_vertex_buffer *_buffers) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS]; + struct pipe_vertex_buffer *buffers = NULL; + unsigned i; + + if (num_buffers) { + memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); + for (i = 0; i < num_buffers; i++) + unwrapped_buffers[i].buffer = identity_buffer_unwrap(_buffers[i].buffer); + buffers = unwrapped_buffers; + } + + pipe->set_vertex_buffers(pipe, + num_buffers, + buffers); +} + +static void +identity_set_vertex_elements(struct pipe_context *_pipe, + unsigned num_elements, + const struct pipe_vertex_element *vertex_elements) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_vertex_elements(pipe, + num_elements, + vertex_elements); +} + +static void +identity_surface_copy(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned dstx, + unsigned dsty, + struct pipe_surface *_src, + unsigned srcx, + unsigned srcy, + unsigned width, + unsigned height) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_surface *id_surface_dst = identity_surface(_dst); + struct identity_surface *id_surface_src = identity_surface(_src); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_surface *dst = id_surface_dst->surface; + struct pipe_surface *src = id_surface_src->surface; + + pipe->surface_copy(pipe, + dst, + dstx, + dsty, + src, + srcx, + srcy, + width, + height); +} + +static void +identity_surface_fill(struct pipe_context *_pipe, + struct pipe_surface *_dst, + unsigned dstx, + unsigned dsty, + unsigned width, + unsigned height, + unsigned value) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_surface *id_surface_dst = identity_surface(_dst); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_surface *dst = id_surface_dst->surface; + + pipe->surface_fill(pipe, + dst, + dstx, + dsty, + width, + height, + value); +} + +static void +identity_clear(struct pipe_context *_pipe, + unsigned buffers, + const float *rgba, + double depth, + unsigned stencil) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->clear(pipe, + buffers, + rgba, + depth, + stencil); +} + +static void +identity_flush(struct pipe_context *_pipe, + unsigned flags, + struct pipe_fence_handle **fence) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->flush(pipe, + flags, + fence); +} + +static unsigned int +identity_is_texture_referenced(struct pipe_context *_pipe, + struct pipe_texture *_texture, + unsigned face, + unsigned level) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_texture *id_texture = identity_texture(_texture); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_texture *texture = id_texture->texture; + + return pipe->is_texture_referenced(pipe, + texture, + face, + level); +} + +static unsigned int +identity_is_buffer_referenced(struct pipe_context *_pipe, + struct pipe_buffer *_buffer) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_buffer *buffer = id_buffer->buffer; + + return pipe->is_buffer_referenced(pipe, + buffer); +} + +struct pipe_context * +identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) +{ + struct identity_context *id_pipe; + (void)identity_screen(_screen); + + id_pipe = CALLOC_STRUCT(identity_context); + if (!id_pipe) { + return NULL; + } + + id_pipe->base.winsys = NULL; + id_pipe->base.screen = _screen; + id_pipe->base.priv = pipe->priv; + id_pipe->base.draw = NULL; + + id_pipe->base.destroy = identity_destroy; + id_pipe->base.set_edgeflags = identity_set_edgeflags; + id_pipe->base.draw_arrays = identity_draw_arrays; + id_pipe->base.draw_elements = identity_draw_elements; + id_pipe->base.draw_range_elements = identity_draw_range_elements; + id_pipe->base.create_query = identity_create_query; + id_pipe->base.destroy_query = identity_destroy_query; + id_pipe->base.begin_query = identity_begin_query; + id_pipe->base.end_query = identity_end_query; + id_pipe->base.get_query_result = identity_get_query_result; + id_pipe->base.create_blend_state = identity_create_blend_state; + id_pipe->base.bind_blend_state = identity_bind_blend_state; + id_pipe->base.delete_blend_state = identity_delete_blend_state; + id_pipe->base.create_sampler_state = identity_create_sampler_state; + id_pipe->base.bind_sampler_states = identity_bind_sampler_states; + id_pipe->base.delete_sampler_state = identity_delete_sampler_state; + id_pipe->base.create_rasterizer_state = identity_create_rasterizer_state; + id_pipe->base.bind_rasterizer_state = identity_bind_rasterizer_state; + id_pipe->base.delete_rasterizer_state = identity_delete_rasterizer_state; + id_pipe->base.create_depth_stencil_alpha_state = identity_create_depth_stencil_alpha_state; + id_pipe->base.bind_depth_stencil_alpha_state = identity_bind_depth_stencil_alpha_state; + id_pipe->base.delete_depth_stencil_alpha_state = identity_delete_depth_stencil_alpha_state; + id_pipe->base.create_fs_state = identity_create_fs_state; + id_pipe->base.bind_fs_state = identity_bind_fs_state; + id_pipe->base.delete_fs_state = identity_delete_fs_state; + id_pipe->base.create_vs_state = identity_create_vs_state; + id_pipe->base.bind_vs_state = identity_bind_vs_state; + id_pipe->base.delete_vs_state = identity_delete_vs_state; + id_pipe->base.set_blend_color = identity_set_blend_color; + id_pipe->base.set_clip_state = identity_set_clip_state; + id_pipe->base.set_constant_buffer = identity_set_constant_buffer; + id_pipe->base.set_framebuffer_state = identity_set_framebuffer_state; + id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple; + id_pipe->base.set_scissor_state = identity_set_scissor_state; + id_pipe->base.set_viewport_state = identity_set_viewport_state; + id_pipe->base.set_sampler_textures = identity_set_sampler_textures; + id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; + id_pipe->base.set_vertex_elements = identity_set_vertex_elements; + id_pipe->base.surface_copy = identity_surface_copy; + id_pipe->base.surface_fill = identity_surface_fill; + id_pipe->base.clear = identity_clear; + id_pipe->base.flush = identity_flush; + id_pipe->base.is_texture_referenced = identity_is_texture_referenced; + id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced; + + id_pipe->pipe = pipe; + + return &id_pipe->base; +} diff --git a/src/gallium/drivers/identity/id_context.h b/src/gallium/drivers/identity/id_context.h new file mode 100644 index 0000000000..75b73fc7df --- /dev/null +++ b/src/gallium/drivers/identity/id_context.h @@ -0,0 +1,48 @@ +/************************************************************************** + * + * 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 VMWARE 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 ID_CONTEXT_H +#define ID_CONTEXT_H + +#include "pipe/p_state.h" +#include "pipe/p_context.h" + + +struct identity_context { + struct pipe_context base; /**< base class */ + + struct pipe_context *pipe; +}; + + +static INLINE struct identity_context * +identity_context(struct pipe_context *pipe) +{ + return (struct identity_context *)pipe; +} + +#endif /* ID_CONTEXT_H */ diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c new file mode 100644 index 0000000000..e893e59940 --- /dev/null +++ b/src/gallium/drivers/identity/id_objects.c @@ -0,0 +1,182 @@ +/************************************************************************** + * + * 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 VMWARE 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 "id_public.h" +#include "id_screen.h" +#include "id_objects.h" + +struct pipe_buffer * +identity_buffer_create(struct identity_screen *id_screen, + struct pipe_buffer *buffer) +{ + struct identity_buffer *id_buffer; + + if(!buffer) + goto error; + + assert(buffer->screen == id_screen->screen); + + id_buffer = CALLOC_STRUCT(identity_buffer); + if(!id_buffer) + goto error; + + memcpy(&id_buffer->base, buffer, sizeof(struct pipe_buffer)); + + pipe_reference_init(&id_buffer->base.reference, 1); + id_buffer->base.screen = &id_screen->base; + id_buffer->buffer = buffer; + + return &id_buffer->base; + +error: + pipe_buffer_reference(&buffer, NULL); + return NULL; +} + +void +identity_buffer_destroy(struct identity_buffer *id_buffer) +{ + pipe_buffer_reference(&id_buffer->buffer, NULL); + FREE(id_buffer); +} + + +struct pipe_texture * +identity_texture_create(struct identity_screen *id_screen, + struct pipe_texture *texture) +{ + struct identity_texture *id_texture; + + if(!texture) + goto error; + + assert(texture->screen == id_screen->screen); + + id_texture = CALLOC_STRUCT(identity_texture); + if(!id_texture) + goto error; + + memcpy(&id_texture->base, texture, sizeof(struct pipe_texture)); + + pipe_reference_init(&id_texture->base.reference, 1); + id_texture->base.screen = &id_screen->base; + id_texture->texture = texture; + + return &id_texture->base; + +error: + pipe_texture_reference(&texture, NULL); + return NULL; +} + +void +identity_texture_destroy(struct identity_texture *id_texture) +{ + pipe_texture_reference(&id_texture->texture, NULL); + FREE(id_texture); +} + + +struct pipe_surface * +identity_surface_create(struct identity_texture *id_texture, + struct pipe_surface *surface) +{ + struct identity_surface *id_surface; + + if(!surface) + goto error; + + assert(surface->texture == id_texture->texture); + + id_surface = CALLOC_STRUCT(identity_surface); + if(!id_surface) + goto error; + + memcpy(&id_surface->base, surface, sizeof(struct pipe_surface)); + + pipe_reference_init(&id_surface->base.reference, 1); + id_surface->base.texture = NULL; + pipe_texture_reference(&id_surface->base.texture, &id_texture->base); + id_surface->surface = surface; + + return &id_surface->base; + +error: + pipe_surface_reference(&surface, NULL); + return NULL; +} + +void +identity_surface_destroy(struct identity_surface *id_surface) +{ + pipe_texture_reference(&id_surface->base.texture, NULL); + pipe_surface_reference(&id_surface->surface, NULL); + FREE(id_surface); +} + + +struct pipe_transfer * +identity_transfer_create(struct identity_texture *id_texture, + struct pipe_transfer *transfer) +{ + struct identity_transfer *id_transfer; + + if(!transfer) + goto error; + + assert(transfer->texture == id_texture->texture); + + id_transfer = CALLOC_STRUCT(identity_transfer); + if(!id_transfer) + goto error; + + memcpy(&id_transfer->base, transfer, sizeof(struct pipe_transfer)); + + id_transfer->base.texture = NULL; + pipe_texture_reference(&id_transfer->base.texture, &id_texture->base); + id_transfer->transfer = transfer; + assert(id_transfer->base.texture == &id_texture->base); + + return &id_transfer->base; + +error: + transfer->texture->screen->tex_transfer_destroy(transfer); + return NULL; +} + +void +identity_transfer_destroy(struct identity_transfer *id_transfer) +{ + struct identity_screen *id_screen = identity_screen(id_transfer->base.texture->screen); + struct pipe_screen *screen = id_screen->screen; + + pipe_texture_reference(&id_transfer->base.texture, NULL); + screen->tex_transfer_destroy(id_transfer->transfer); + FREE(id_transfer); +} diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h new file mode 100644 index 0000000000..ce58faa3c7 --- /dev/null +++ b/src/gallium/drivers/identity/id_objects.h @@ -0,0 +1,169 @@ +/************************************************************************** + * + * 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 VMWARE 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 ID_OBJECTS_H +#define ID_OBJECTS_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + +#include "id_screen.h" + + +struct identity_buffer +{ + struct pipe_buffer base; + + struct pipe_buffer *buffer; +}; + + +struct identity_texture +{ + struct pipe_texture base; + + struct pipe_texture *texture; +}; + + +struct identity_surface +{ + struct pipe_surface base; + + struct pipe_surface *surface; +}; + + +struct identity_transfer +{ + struct pipe_transfer base; + + struct pipe_transfer *transfer; +}; + + +static INLINE struct identity_buffer * +identity_buffer(struct pipe_buffer *_buffer) +{ + if(!_buffer) + return NULL; + (void)identity_screen(_buffer->screen); + return (struct identity_buffer *)_buffer; +} + +static INLINE struct identity_texture * +identity_texture(struct pipe_texture *_texture) +{ + if(!_texture) + return NULL; + (void)identity_screen(_texture->screen); + return (struct identity_texture *)_texture; +} + +static INLINE struct identity_surface * +identity_surface(struct pipe_surface *_surface) +{ + if(!_surface) + return NULL; + (void)identity_texture(_surface->texture); + return (struct identity_surface *)_surface; +} + +static INLINE struct identity_transfer * +identity_transfer(struct pipe_transfer *_transfer) +{ + if(!_transfer) + return NULL; + (void)identity_texture(_transfer->texture); + return (struct identity_transfer *)_transfer; +} + + +static INLINE struct pipe_buffer * +identity_buffer_unwrap(struct pipe_buffer *_buffer) +{ + if(!_buffer) + return NULL; + return identity_buffer(_buffer)->buffer; +} + +static INLINE struct pipe_texture * +identity_texture_unwrap(struct pipe_texture *_texture) +{ + if(!_texture) + return NULL; + return identity_texture(_texture)->texture; +} + +static INLINE struct pipe_surface * +identity_surface_unwrap(struct pipe_surface *_surface) +{ + if(!_surface) + return NULL; + return identity_surface(_surface)->surface; +} + +static INLINE struct pipe_transfer * +identity_transfer_unwrap(struct pipe_transfer *_transfer) +{ + if(!_transfer) + return NULL; + return identity_transfer(_transfer)->transfer; +} + + +struct pipe_buffer * +identity_buffer_create(struct identity_screen *id_screen, + struct pipe_buffer *buffer); + +void +identity_buffer_destroy(struct identity_buffer *id_buffer); + +struct pipe_texture * +identity_texture_create(struct identity_screen *id_screen, + struct pipe_texture *texture); + +void +identity_texture_destroy(struct identity_texture *id_texture); + +struct pipe_surface * +identity_surface_create(struct identity_texture *id_texture, + struct pipe_surface *surface); + +void +identity_surface_destroy(struct identity_surface *id_surface); + +struct pipe_transfer * +identity_transfer_create(struct identity_texture *id_texture, + struct pipe_transfer *transfer); + +void +identity_transfer_destroy(struct identity_transfer *id_transfer); + + +#endif /* ID_OBJECTS_H */ diff --git a/src/gallium/drivers/identity/id_public.h b/src/gallium/drivers/identity/id_public.h new file mode 100644 index 0000000000..cac14cfd60 --- /dev/null +++ b/src/gallium/drivers/identity/id_public.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * 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 VMWARE 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 ID_PUBLIC_H +#define ID_PUBLIC_H + +struct pipe_screen; +struct pipe_context; + +struct pipe_screen * +identity_screen_create(struct pipe_screen *screen); + +struct pipe_context * +identity_context_create(struct pipe_screen *screen, struct pipe_context *pipe); + +#endif /* PT_PUBLIC_H */ diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c new file mode 100644 index 0000000000..259f1be36e --- /dev/null +++ b/src/gallium/drivers/identity/id_screen.c @@ -0,0 +1,481 @@ +/************************************************************************** + * + * 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "pipe/p_screen.h" +#include "pipe/p_state.h" +#include "util/u_memory.h" + +#include "id_public.h" +#include "id_screen.h" +#include "id_objects.h" + + +static void +identity_screen_destroy(struct pipe_screen *_screen) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + screen->destroy(screen); + + FREE(id_screen); +} + +static const char * +identity_screen_get_name(struct pipe_screen *_screen) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->get_name(screen); +} + +static const char * +identity_screen_get_vendor(struct pipe_screen *_screen) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->get_vendor(screen); +} + +static int +identity_screen_get_param(struct pipe_screen *_screen, + int param) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->get_param(screen, + param); +} + +static float +identity_screen_get_paramf(struct pipe_screen *_screen, + int param) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->get_paramf(screen, + param); +} + +static boolean +identity_screen_is_format_supported(struct pipe_screen *_screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->is_format_supported(screen, + format, + target, + tex_usage, + geom_flags); +} + +static struct pipe_texture * +identity_screen_texture_create(struct pipe_screen *_screen, + const struct pipe_texture *templat) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_texture *result; + + result = screen->texture_create(screen, + templat); + + if (result) + return identity_texture_create(id_screen, result); + return NULL; +} + +static struct pipe_texture * +identity_screen_texture_blanket(struct pipe_screen *_screen, + const struct pipe_texture *templat, + const unsigned *stride, + struct pipe_buffer *_buffer) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + struct pipe_texture *result; + + result = screen->texture_blanket(screen, + templat, + stride, + buffer); + + if (result) + return identity_texture_create(id_screen, result); + return NULL; +} + +static void +identity_screen_texture_destroy(struct pipe_texture *_texture) +{ + identity_texture_destroy(identity_texture(_texture)); +} + +static struct pipe_surface * +identity_screen_get_tex_surface(struct pipe_screen *_screen, + struct pipe_texture *_texture, + unsigned face, + unsigned level, + unsigned zslice, + unsigned usage) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_texture *id_texture = identity_texture(_texture); + struct pipe_screen *screen = id_screen->screen; + struct pipe_texture *texture = id_texture->texture; + struct pipe_surface *result; + + result = screen->get_tex_surface(screen, + texture, + face, + level, + zslice, + usage); + + if (result) + return identity_surface_create(id_texture, result); + return NULL; +} + +static void +identity_screen_tex_surface_destroy(struct pipe_surface *_surface) +{ + identity_surface_destroy(identity_surface(_surface)); +} + +static struct pipe_transfer * +identity_screen_get_tex_transfer(struct pipe_screen *_screen, + struct pipe_texture *_texture, + unsigned face, + unsigned level, + unsigned zslice, + enum pipe_transfer_usage usage, + unsigned x, + unsigned y, + unsigned w, + unsigned h) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_texture *id_texture = identity_texture(_texture); + struct pipe_screen *screen = id_screen->screen; + struct pipe_texture *texture = id_texture->texture; + struct pipe_transfer *result; + + result = screen->get_tex_transfer(screen, + texture, + face, + level, + zslice, + usage, + x, + y, + w, + h); + + if (result) + return identity_transfer_create(id_texture, result); + return NULL; +} + +static void +identity_screen_tex_transfer_destroy(struct pipe_transfer *_transfer) +{ + identity_transfer_destroy(identity_transfer(_transfer)); +} + +static void * +identity_screen_transfer_map(struct pipe_screen *_screen, + struct pipe_transfer *_transfer) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_transfer *id_transfer = identity_transfer(_transfer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_transfer *transfer = id_transfer->transfer; + + return screen->transfer_map(screen, + transfer); +} + +static void +identity_screen_transfer_unmap(struct pipe_screen *_screen, + struct pipe_transfer *_transfer) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_transfer *id_transfer = identity_transfer(_transfer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_transfer *transfer = id_transfer->transfer; + + screen->transfer_unmap(screen, + transfer); +} + +static struct pipe_buffer * +identity_screen_buffer_create(struct pipe_screen *_screen, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *result; + + result = screen->buffer_create(screen, + alignment, + usage, + size); + + if (result) + return identity_buffer_create(id_screen, result); + return NULL; +} + +static struct pipe_buffer * +identity_screen_user_buffer_create(struct pipe_screen *_screen, + void *ptr, + unsigned bytes) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *result; + + result = screen->user_buffer_create(screen, + ptr, + bytes); + + if (result) + return identity_buffer_create(id_screen, result); + return NULL; +} + +static struct pipe_buffer * +identity_screen_surface_buffer_create(struct pipe_screen *_screen, + unsigned width, + unsigned height, + enum pipe_format format, + unsigned usage, + unsigned *stride) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *result; + + result = screen->surface_buffer_create(screen, + width, + height, + format, + usage, + stride); + + if (result) + return identity_buffer_create(id_screen, result); + return NULL; +} + +static void * +identity_screen_buffer_map(struct pipe_screen *_screen, + struct pipe_buffer *_buffer, + unsigned usage) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + + return screen->buffer_map(screen, + buffer, + usage); +} + +static void * +identity_screen_buffer_map_range(struct pipe_screen *_screen, + struct pipe_buffer *_buffer, + unsigned offset, + unsigned length, + unsigned usage) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + + return screen->buffer_map_range(screen, + buffer, + offset, + length, + usage); +} + +static void +identity_screen_buffer_flush_mapped_range(struct pipe_screen *_screen, + struct pipe_buffer *_buffer, + unsigned offset, + unsigned length) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + + screen->buffer_flush_mapped_range(screen, + buffer, + offset, + length); +} + +static void +identity_screen_buffer_unmap(struct pipe_screen *_screen, + struct pipe_buffer *_buffer) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_buffer *id_buffer = identity_buffer(_buffer); + struct pipe_screen *screen = id_screen->screen; + struct pipe_buffer *buffer = id_buffer->buffer; + + screen->buffer_unmap(screen, + buffer); +} + +static void +identity_screen_buffer_destroy(struct pipe_buffer *_buffer) +{ + identity_buffer_destroy(identity_buffer(_buffer)); +} + +static void +identity_screen_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_surface *_surface, + void *context_private) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct identity_surface *id_surface = identity_surface(_surface); + struct pipe_screen *screen = id_screen->screen; + struct pipe_surface *surface = id_surface->surface; + + screen->flush_frontbuffer(screen, + surface, + context_private); +} + +static void +identity_screen_fence_reference(struct pipe_screen *_screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + screen->fence_reference(screen, + ptr, + fence); +} + +static int +identity_screen_fence_signalled(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->fence_signalled(screen, + fence, + flags); +} + +static int +identity_screen_fence_finish(struct pipe_screen *_screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + struct identity_screen *id_screen = identity_screen(_screen); + struct pipe_screen *screen = id_screen->screen; + + return screen->fence_finish(screen, + fence, + flags); +} + +struct pipe_screen * +identity_screen_create(struct pipe_screen *screen) +{ + struct identity_screen *id_screen; + + id_screen = CALLOC_STRUCT(identity_screen); + if (!id_screen) { + return NULL; + } + + id_screen->base.winsys = NULL; + + id_screen->base.destroy = identity_screen_destroy; + id_screen->base.get_name = identity_screen_get_name; + id_screen->base.get_vendor = identity_screen_get_vendor; + id_screen->base.get_param = identity_screen_get_param; + id_screen->base.get_paramf = identity_screen_get_paramf; + id_screen->base.is_format_supported = identity_screen_is_format_supported; + id_screen->base.texture_create = identity_screen_texture_create; + id_screen->base.texture_blanket = identity_screen_texture_blanket; + id_screen->base.texture_destroy = identity_screen_texture_destroy; + id_screen->base.get_tex_surface = identity_screen_get_tex_surface; + id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy; + id_screen->base.get_tex_transfer = identity_screen_get_tex_transfer; + id_screen->base.tex_transfer_destroy = identity_screen_tex_transfer_destroy; + id_screen->base.transfer_map = identity_screen_transfer_map; + id_screen->base.transfer_unmap = identity_screen_transfer_unmap; + id_screen->base.buffer_create = identity_screen_buffer_create; + id_screen->base.user_buffer_create = identity_screen_user_buffer_create; + id_screen->base.surface_buffer_create = identity_screen_surface_buffer_create; + if (screen->buffer_map) + id_screen->base.buffer_map = identity_screen_buffer_map; + if (screen->buffer_map_range) + id_screen->base.buffer_map_range = identity_screen_buffer_map_range; + if (screen->buffer_flush_mapped_range) + id_screen->base.buffer_flush_mapped_range = identity_screen_buffer_flush_mapped_range; + if (screen->buffer_unmap) + id_screen->base.buffer_unmap = identity_screen_buffer_unmap; + id_screen->base.buffer_destroy = identity_screen_buffer_destroy; + id_screen->base.flush_frontbuffer = identity_screen_flush_frontbuffer; + id_screen->base.fence_reference = identity_screen_fence_reference; + id_screen->base.fence_signalled = identity_screen_fence_signalled; + id_screen->base.fence_finish = identity_screen_fence_finish; + + id_screen->screen = screen; + + return &id_screen->base; +} diff --git a/src/gallium/drivers/identity/id_screen.h b/src/gallium/drivers/identity/id_screen.h new file mode 100644 index 0000000000..2c4f129089 --- /dev/null +++ b/src/gallium/drivers/identity/id_screen.h @@ -0,0 +1,48 @@ +/************************************************************************** + * + * 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 VMWARE 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 ID_SCREEN_H +#define ID_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + + +struct identity_screen { + struct pipe_screen base; + + struct pipe_screen *screen; +}; + + +static INLINE struct identity_screen * +identity_screen(struct pipe_screen *screen) +{ + return (struct identity_screen *)screen; +} + +#endif /* ID_SCREEN_H */ -- cgit v1.2.3 From d22bd1421cdfa1900df5b76e6f862596bdd11074 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Tue, 25 Aug 2009 15:39:05 +0200 Subject: Add support for building the Xorg state tracker with scons. scons ... statetrackers=xorg --- SConstruct | 2 +- src/gallium/SConscript | 1 + src/gallium/state_trackers/xorg/SConscript | 26 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/gallium/state_trackers/xorg/SConscript (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 4a0fb94deb..59d05bc54f 100644 --- a/SConstruct +++ b/SConstruct @@ -44,7 +44,7 @@ else: opts = Variables('config.py') common.AddOptions(opts) opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers, - ['mesa', 'python'])) + ['mesa', 'python', 'xorg'])) opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers, ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity'])) opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys, diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 32b7c2980a..89c69d7205 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -31,6 +31,7 @@ for driver in env['drivers']: SConscript('state_trackers/python/SConscript') SConscript('state_trackers/glx/xlib/SConscript') SConscript('state_trackers/dri/SConscript') +SConscript('state_trackers/xorg/SConscript') if platform == 'windows': SConscript('state_trackers/wgl/SConscript') diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript new file mode 100644 index 0000000000..15ebcf8673 --- /dev/null +++ b/src/gallium/state_trackers/xorg/SConscript @@ -0,0 +1,26 @@ +####################################################################### +# SConscript for xorg state_tracker + +Import('*') + +if 'xorg' in env['statetrackers']: + + env = env.Clone() + + env.Append(CPPPATH = [ + '#/src/mesa', + ]) + + env.ParseConfig('pkg-config --cflags --libs xorg-server') + + st_xorg = env.ConvenienceLibrary( + target = 'st_xorg', + source = [ 'xorg_composite.c', + 'xorg_crtc.c', + 'xorg_dri2.c', + 'xorg_driver.c', + 'xorg_exa.c', + 'xorg_output.c', + ] + ) + Export('st_xorg') -- cgit v1.2.3 From 946f432a08112148d743eb9faf6b27bb8cc7fa76 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 26 Jul 2009 23:44:38 +0100 Subject: llvmpipe: Fork softpipe for experimentation with llvm. --- SConstruct | 4 +- src/gallium/drivers/llvmpipe/Makefile | 44 + src/gallium/drivers/llvmpipe/SConscript | 46 + src/gallium/drivers/llvmpipe/lp_clear.c | 89 ++ src/gallium/drivers/llvmpipe/lp_clear.h | 43 + src/gallium/drivers/llvmpipe/lp_context.c | 317 ++++ src/gallium/drivers/llvmpipe/lp_context.h | 168 +++ src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 194 +++ src/gallium/drivers/llvmpipe/lp_flush.c | 94 ++ src/gallium/drivers/llvmpipe/lp_flush.h | 37 + src/gallium/drivers/llvmpipe/lp_fs.h | 54 + src/gallium/drivers/llvmpipe/lp_fs_exec.c | 162 ++ src/gallium/drivers/llvmpipe/lp_fs_llvm.c | 205 +++ src/gallium/drivers/llvmpipe/lp_fs_sse.c | 169 +++ src/gallium/drivers/llvmpipe/lp_prim_setup.c | 190 +++ src/gallium/drivers/llvmpipe/lp_prim_setup.h | 85 ++ src/gallium/drivers/llvmpipe/lp_prim_vbuf.c | 585 ++++++++ src/gallium/drivers/llvmpipe/lp_prim_vbuf.h | 38 + src/gallium/drivers/llvmpipe/lp_quad.h | 106 ++ src/gallium/drivers/llvmpipe/lp_quad_alpha_test.c | 108 ++ src/gallium/drivers/llvmpipe/lp_quad_blend.c | 777 ++++++++++ src/gallium/drivers/llvmpipe/lp_quad_bufloop.c | 74 + src/gallium/drivers/llvmpipe/lp_quad_colormask.c | 116 ++ src/gallium/drivers/llvmpipe/lp_quad_coverage.c | 94 ++ src/gallium/drivers/llvmpipe/lp_quad_depth_test.c | 290 ++++ src/gallium/drivers/llvmpipe/lp_quad_earlyz.c | 88 ++ src/gallium/drivers/llvmpipe/lp_quad_fs.c | 192 +++ src/gallium/drivers/llvmpipe/lp_quad_occlusion.c | 85 ++ src/gallium/drivers/llvmpipe/lp_quad_output.c | 103 ++ src/gallium/drivers/llvmpipe/lp_quad_pipe.c | 118 ++ src/gallium/drivers/llvmpipe/lp_quad_pipe.h | 74 + src/gallium/drivers/llvmpipe/lp_quad_stencil.c | 352 +++++ src/gallium/drivers/llvmpipe/lp_quad_stipple.c | 77 + src/gallium/drivers/llvmpipe/lp_query.c | 111 ++ src/gallium/drivers/llvmpipe/lp_query.h | 39 + src/gallium/drivers/llvmpipe/lp_screen.c | 190 +++ src/gallium/drivers/llvmpipe/lp_screen.h | 58 + src/gallium/drivers/llvmpipe/lp_setup.c | 1550 ++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_setup.h | 53 + src/gallium/drivers/llvmpipe/lp_state.h | 206 +++ src/gallium/drivers/llvmpipe/lp_state_blend.c | 98 ++ src/gallium/drivers/llvmpipe/lp_state_clip.c | 79 + src/gallium/drivers/llvmpipe/lp_state_derived.c | 211 +++ src/gallium/drivers/llvmpipe/lp_state_fs.c | 169 +++ src/gallium/drivers/llvmpipe/lp_state_rasterizer.c | 62 + src/gallium/drivers/llvmpipe/lp_state_sampler.c | 117 ++ src/gallium/drivers/llvmpipe/lp_state_surface.c | 129 ++ src/gallium/drivers/llvmpipe/lp_state_vertex.c | 73 + src/gallium/drivers/llvmpipe/lp_surface.c | 50 + src/gallium/drivers/llvmpipe/lp_surface.h | 42 + src/gallium/drivers/llvmpipe/lp_tex_sample.c | 1295 ++++++++++++++++ src/gallium/drivers/llvmpipe/lp_tex_sample.h | 73 + src/gallium/drivers/llvmpipe/lp_texture.c | 421 ++++++ src/gallium/drivers/llvmpipe/lp_texture.h | 83 ++ src/gallium/drivers/llvmpipe/lp_tile_cache.c | 626 ++++++++ src/gallium/drivers/llvmpipe/lp_tile_cache.h | 106 ++ src/gallium/drivers/llvmpipe/lp_winsys.h | 65 + 57 files changed, 11082 insertions(+), 2 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/Makefile create mode 100644 src/gallium/drivers/llvmpipe/SConscript create mode 100644 src/gallium/drivers/llvmpipe/lp_clear.c create mode 100644 src/gallium/drivers/llvmpipe/lp_clear.h create mode 100644 src/gallium/drivers/llvmpipe/lp_context.c create mode 100644 src/gallium/drivers/llvmpipe/lp_context.h create mode 100644 src/gallium/drivers/llvmpipe/lp_draw_arrays.c create mode 100644 src/gallium/drivers/llvmpipe/lp_flush.c create mode 100644 src/gallium/drivers/llvmpipe/lp_flush.h create mode 100644 src/gallium/drivers/llvmpipe/lp_fs.h create mode 100644 src/gallium/drivers/llvmpipe/lp_fs_exec.c create mode 100644 src/gallium/drivers/llvmpipe/lp_fs_llvm.c create mode 100644 src/gallium/drivers/llvmpipe/lp_fs_sse.c create mode 100644 src/gallium/drivers/llvmpipe/lp_prim_setup.c create mode 100644 src/gallium/drivers/llvmpipe/lp_prim_setup.h create mode 100644 src/gallium/drivers/llvmpipe/lp_prim_vbuf.c create mode 100644 src/gallium/drivers/llvmpipe/lp_prim_vbuf.h create mode 100644 src/gallium/drivers/llvmpipe/lp_quad.h create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_alpha_test.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_blend.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_bufloop.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_colormask.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_coverage.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_depth_test.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_earlyz.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_fs.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_occlusion.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_output.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_pipe.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_pipe.h create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_stencil.c create mode 100644 src/gallium/drivers/llvmpipe/lp_quad_stipple.c create mode 100644 src/gallium/drivers/llvmpipe/lp_query.c create mode 100644 src/gallium/drivers/llvmpipe/lp_query.h create mode 100644 src/gallium/drivers/llvmpipe/lp_screen.c create mode 100644 src/gallium/drivers/llvmpipe/lp_screen.h create mode 100644 src/gallium/drivers/llvmpipe/lp_setup.c create mode 100644 src/gallium/drivers/llvmpipe/lp_setup.h create mode 100644 src/gallium/drivers/llvmpipe/lp_state.h create mode 100644 src/gallium/drivers/llvmpipe/lp_state_blend.c create mode 100644 src/gallium/drivers/llvmpipe/lp_state_clip.c create mode 100644 src/gallium/drivers/llvmpipe/lp_state_derived.c create mode 100644 src/gallium/drivers/llvmpipe/lp_state_fs.c create mode 100644 src/gallium/drivers/llvmpipe/lp_state_rasterizer.c create mode 100644 src/gallium/drivers/llvmpipe/lp_state_sampler.c create mode 100644 src/gallium/drivers/llvmpipe/lp_state_surface.c create mode 100644 src/gallium/drivers/llvmpipe/lp_state_vertex.c create mode 100644 src/gallium/drivers/llvmpipe/lp_surface.c create mode 100644 src/gallium/drivers/llvmpipe/lp_surface.h create mode 100644 src/gallium/drivers/llvmpipe/lp_tex_sample.c create mode 100644 src/gallium/drivers/llvmpipe/lp_tex_sample.h create mode 100644 src/gallium/drivers/llvmpipe/lp_texture.c create mode 100644 src/gallium/drivers/llvmpipe/lp_texture.h create mode 100644 src/gallium/drivers/llvmpipe/lp_tile_cache.c create mode 100644 src/gallium/drivers/llvmpipe/lp_tile_cache.h create mode 100644 src/gallium/drivers/llvmpipe/lp_winsys.h (limited to 'SConstruct') diff --git a/SConstruct b/SConstruct index 59d05bc54f..e9baab0947 100644 --- a/SConstruct +++ b/SConstruct @@ -32,7 +32,7 @@ import common default_statetrackers = 'mesa' if common.default_platform in ('linux', 'freebsd', 'darwin'): - default_drivers = 'softpipe,failover,i915simple,trace,identity' + default_drivers = 'softpipe,failover,i915simple,trace,identity,llvmpipe' default_winsys = 'xlib' elif common.default_platform in ('winddk',): default_drivers = 'softpipe,i915simple,trace,identity' @@ -46,7 +46,7 @@ common.AddOptions(opts) opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers, ['mesa', 'python', 'xorg'])) opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers, - ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity'])) + ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity', 'llvmpipe'])) opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys, ['xlib', 'intel', 'gdi', 'radeon'])) diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile new file mode 100644 index 0000000000..c0c430628d --- /dev/null +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -0,0 +1,44 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = llvmpipe + +C_SOURCES = \ + lp_fs_exec.c \ + lp_fs_sse.c \ + lp_fs_llvm.c \ + lp_clear.c \ + lp_flush.c \ + lp_query.c \ + lp_context.c \ + lp_draw_arrays.c \ + lp_prim_setup.c \ + lp_prim_vbuf.c \ + lp_quad_pipe.c \ + lp_quad_alpha_test.c \ + lp_quad_blend.c \ + lp_quad_colormask.c \ + lp_quad_coverage.c \ + lp_quad_depth_test.c \ + lp_quad_earlyz.c \ + lp_quad_fs.c \ + lp_quad_occlusion.c \ + lp_quad_output.c \ + lp_quad_stencil.c \ + lp_quad_stipple.c \ + lp_screen.c \ + lp_setup.c \ + lp_state_blend.c \ + lp_state_clip.c \ + lp_state_derived.c \ + lp_state_fs.c \ + lp_state_sampler.c \ + lp_state_rasterizer.c \ + lp_state_surface.c \ + lp_state_vertex.c \ + lp_texture.c \ + lp_tex_sample.c \ + lp_tile_cache.c \ + lp_surface.c + +include ../../Makefile.template diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript new file mode 100644 index 0000000000..f021549c44 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -0,0 +1,46 @@ +Import('*') + +env = env.Clone() + +llvmpipe = env.ConvenienceLibrary( + target = 'llvmpipe', + source = [ + 'lp_fs_exec.c', + 'lp_fs_sse.c', + 'lp_fs_llvm.c', + 'lp_clear.c', + 'lp_context.c', + 'lp_draw_arrays.c', + 'lp_flush.c', + 'lp_prim_setup.c', + 'lp_prim_vbuf.c', + 'lp_setup.c', + 'lp_quad_alpha_test.c', + 'lp_quad_blend.c', + 'lp_quad_pipe.c', + 'lp_quad_colormask.c', + 'lp_quad_coverage.c', + 'lp_quad_depth_test.c', + 'lp_quad_earlyz.c', + 'lp_quad_fs.c', + 'lp_quad_occlusion.c', + 'lp_quad_output.c', + 'lp_quad_stencil.c', + 'lp_quad_stipple.c', + 'lp_query.c', + 'lp_screen.c', + 'lp_state_blend.c', + 'lp_state_clip.c', + 'lp_state_derived.c', + 'lp_state_fs.c', + 'lp_state_rasterizer.c', + 'lp_state_sampler.c', + 'lp_state_surface.c', + 'lp_state_vertex.c', + 'lp_surface.c', + 'lp_tex_sample.c', + 'lp_texture.c', + 'lp_tile_cache.c', + ]) + +Export('softpipe') \ No newline at end of file diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c new file mode 100644 index 0000000000..4a7ffde1b9 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_clear.c @@ -0,0 +1,89 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * 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. + * + **************************************************************************/ + +/* Author: + * Brian Paul + * Michel Dänzer + */ + + +#include "pipe/p_defines.h" +#include "util/u_pack_color.h" +#include "lp_clear.h" +#include "lp_context.h" +#include "lp_surface.h" +#include "lp_state.h" +#include "lp_tile_cache.h" + + +/** + * Clear the given buffers to the specified values. + * No masking, no scissor (clear entire buffer). + */ +void +llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + unsigned cv; + uint i; + + if (llvmpipe->no_rast) + return; + +#if 0 + llvmpipe_update_derived(llvmpipe); /* not needed?? */ +#endif + + if (buffers & PIPE_CLEAR_COLOR) { + for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { + struct pipe_surface *ps = llvmpipe->framebuffer.cbufs[i]; + + util_pack_color(rgba, ps->format, &cv); + lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, cv); + +#if !TILE_CLEAR_OPTIMIZATION + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); +#endif + } + } + + if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { + static const float zero[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; + struct pipe_surface *ps = llvmpipe->framebuffer.zsbuf; + + cv = util_pack_z_stencil(ps->format, depth, stencil); + lp_tile_cache_clear(llvmpipe->zsbuf_cache, zero, cv); + +#if !TILE_CLEAR_OPTIMIZATION + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv); +#endif + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_clear.h b/src/gallium/drivers/llvmpipe/lp_clear.h new file mode 100644 index 0000000000..781a867946 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_clear.h @@ -0,0 +1,43 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Brian Paul + */ + +#ifndef SP_CLEAR_H +#define SP_CLEAR_H + +#include "pipe/p_state.h" +struct pipe_context; + +extern void +llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); + + +#endif /* SP_CLEAR_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c new file mode 100644 index 0000000000..cad74d3da9 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -0,0 +1,317 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * Copyright 2008 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "lp_clear.h" +#include "lp_context.h" +#include "lp_flush.h" +#include "lp_prim_setup.h" +#include "lp_prim_vbuf.h" +#include "lp_state.h" +#include "lp_surface.h" +#include "lp_tile_cache.h" +#include "lp_texture.h" +#include "lp_winsys.h" +#include "lp_query.h" + + + +/** + * Map any drawing surfaces which aren't already mapped + */ +void +llvmpipe_map_transfers(struct llvmpipe_context *lp) +{ + unsigned i; + + for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { + lp_tile_cache_map_transfers(lp->cbuf_cache[i]); + } + + lp_tile_cache_map_transfers(lp->zsbuf_cache); +} + + +/** + * Unmap any mapped drawing surfaces + */ +void +llvmpipe_unmap_transfers(struct llvmpipe_context *lp) +{ + uint i; + + for (i = 0; i < lp->framebuffer.nr_cbufs; i++) + lp_flush_tile_cache(lp, lp->cbuf_cache[i]); + lp_flush_tile_cache(lp, lp->zsbuf_cache); + + for (i = 0; i < lp->framebuffer.nr_cbufs; i++) { + lp_tile_cache_unmap_transfers(lp->cbuf_cache[i]); + } + lp_tile_cache_unmap_transfers(lp->zsbuf_cache); +} + + +static void llvmpipe_destroy( struct pipe_context *pipe ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + uint i; + + if (llvmpipe->draw) + draw_destroy( llvmpipe->draw ); + + for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { + llvmpipe->quad[i].polygon_stipple->destroy( llvmpipe->quad[i].polygon_stipple ); + llvmpipe->quad[i].earlyz->destroy( llvmpipe->quad[i].earlyz ); + llvmpipe->quad[i].shade->destroy( llvmpipe->quad[i].shade ); + llvmpipe->quad[i].alpha_test->destroy( llvmpipe->quad[i].alpha_test ); + llvmpipe->quad[i].depth_test->destroy( llvmpipe->quad[i].depth_test ); + llvmpipe->quad[i].stencil_test->destroy( llvmpipe->quad[i].stencil_test ); + llvmpipe->quad[i].occlusion->destroy( llvmpipe->quad[i].occlusion ); + llvmpipe->quad[i].coverage->destroy( llvmpipe->quad[i].coverage ); + llvmpipe->quad[i].blend->destroy( llvmpipe->quad[i].blend ); + llvmpipe->quad[i].colormask->destroy( llvmpipe->quad[i].colormask ); + llvmpipe->quad[i].output->destroy( llvmpipe->quad[i].output ); + } + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + lp_destroy_tile_cache(llvmpipe->cbuf_cache[i]); + lp_destroy_tile_cache(llvmpipe->zsbuf_cache); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + lp_destroy_tile_cache(llvmpipe->tex_cache[i]); + + for (i = 0; i < Elements(llvmpipe->constants); i++) { + if (llvmpipe->constants[i].buffer) { + pipe_buffer_reference(&llvmpipe->constants[i].buffer, NULL); + } + } + + FREE( llvmpipe ); +} + +static unsigned int +llvmpipe_is_texture_referenced( struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, unsigned level) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + unsigned i; + + if(llvmpipe->dirty_render_cache) { + for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { + if(llvmpipe->framebuffer.cbufs[i] && + llvmpipe->framebuffer.cbufs[i]->texture == texture) + return PIPE_REFERENCED_FOR_WRITE; + } + if(llvmpipe->framebuffer.zsbuf && + llvmpipe->framebuffer.zsbuf->texture == texture) + return PIPE_REFERENCED_FOR_WRITE; + } + + /* FIXME: we also need to do the same for the texture cache */ + + return PIPE_UNREFERENCED; +} + +static unsigned int +llvmpipe_is_buffer_referenced( struct pipe_context *pipe, + struct pipe_buffer *buf) +{ + return PIPE_UNREFERENCED; +} + +struct pipe_context * +llvmpipe_create( struct pipe_screen *screen ) +{ + struct llvmpipe_context *llvmpipe = CALLOC_STRUCT(llvmpipe_context); + uint i; + + util_init_math(); + +#ifdef PIPE_ARCH_X86 + llvmpipe->use_sse = !debug_get_bool_option( "GALLIUM_NOSSE", FALSE ); +#else + llvmpipe->use_sse = FALSE; +#endif + + llvmpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE ); + + llvmpipe->pipe.winsys = screen->winsys; + llvmpipe->pipe.screen = screen; + llvmpipe->pipe.destroy = llvmpipe_destroy; + + /* state setters */ + llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state; + llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state; + llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state; + + llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state; + llvmpipe->pipe.bind_sampler_states = llvmpipe_bind_sampler_states; + llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state; + + llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state; + llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state; + llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state; + + llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state; + llvmpipe->pipe.bind_rasterizer_state = llvmpipe_bind_rasterizer_state; + llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state; + + llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state; + llvmpipe->pipe.bind_fs_state = llvmpipe_bind_fs_state; + llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state; + + llvmpipe->pipe.create_vs_state = llvmpipe_create_vs_state; + llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state; + llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state; + + llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color; + llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state; + llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer; + llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state; + llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple; + llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state; + llvmpipe->pipe.set_sampler_textures = llvmpipe_set_sampler_textures; + llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state; + + llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers; + llvmpipe->pipe.set_vertex_elements = llvmpipe_set_vertex_elements; + + llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays; + llvmpipe->pipe.draw_elements = llvmpipe_draw_elements; + llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements; + llvmpipe->pipe.set_edgeflags = llvmpipe_set_edgeflags; + + + llvmpipe->pipe.clear = llvmpipe_clear; + llvmpipe->pipe.flush = llvmpipe_flush; + + llvmpipe->pipe.is_texture_referenced = llvmpipe_is_texture_referenced; + llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced; + + llvmpipe_init_query_funcs( llvmpipe ); + llvmpipe_init_texture_funcs( llvmpipe ); + + /* + * Alloc caches for accessing drawing surfaces and textures. + * Must be before quad stage setup! + */ + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + llvmpipe->cbuf_cache[i] = lp_create_tile_cache( screen ); + llvmpipe->zsbuf_cache = lp_create_tile_cache( screen ); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) + llvmpipe->tex_cache[i] = lp_create_tile_cache( screen ); + + + /* setup quad rendering stages */ + for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { + llvmpipe->quad[i].polygon_stipple = lp_quad_polygon_stipple_stage(llvmpipe); + llvmpipe->quad[i].earlyz = lp_quad_earlyz_stage(llvmpipe); + llvmpipe->quad[i].shade = lp_quad_shade_stage(llvmpipe); + llvmpipe->quad[i].alpha_test = lp_quad_alpha_test_stage(llvmpipe); + llvmpipe->quad[i].depth_test = lp_quad_depth_test_stage(llvmpipe); + llvmpipe->quad[i].stencil_test = lp_quad_stencil_test_stage(llvmpipe); + llvmpipe->quad[i].occlusion = lp_quad_occlusion_stage(llvmpipe); + llvmpipe->quad[i].coverage = lp_quad_coverage_stage(llvmpipe); + llvmpipe->quad[i].blend = lp_quad_blend_stage(llvmpipe); + llvmpipe->quad[i].colormask = lp_quad_colormask_stage(llvmpipe); + llvmpipe->quad[i].output = lp_quad_output_stage(llvmpipe); + } + + /* vertex shader samplers */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples_vertex; + llvmpipe->tgsi.vert_samplers[i].unit = i; + llvmpipe->tgsi.vert_samplers[i].lp = llvmpipe; + llvmpipe->tgsi.vert_samplers[i].cache = llvmpipe->tex_cache[i]; + llvmpipe->tgsi.vert_samplers_list[i] = &llvmpipe->tgsi.vert_samplers[i]; + } + + /* fragment shader samplers */ + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples_fragment; + llvmpipe->tgsi.frag_samplers[i].unit = i; + llvmpipe->tgsi.frag_samplers[i].lp = llvmpipe; + llvmpipe->tgsi.frag_samplers[i].cache = llvmpipe->tex_cache[i]; + llvmpipe->tgsi.frag_samplers_list[i] = &llvmpipe->tgsi.frag_samplers[i]; + } + + /* + * Create drawing context and plug our rendering stage into it. + */ + llvmpipe->draw = draw_create(); + if (!llvmpipe->draw) + goto fail; + + draw_texture_samplers(llvmpipe->draw, + PIPE_MAX_SAMPLERS, + (struct tgsi_sampler **) + llvmpipe->tgsi.vert_samplers_list); + + llvmpipe->setup = lp_draw_render_stage(llvmpipe); + if (!llvmpipe->setup) + goto fail; + + if (debug_get_bool_option( "SP_NO_RAST", FALSE )) + llvmpipe->no_rast = TRUE; + + if (debug_get_bool_option( "SP_NO_VBUF", FALSE )) { + /* Deprecated path -- vbuf is the intended interface to the draw module: + */ + draw_set_rasterize_stage(llvmpipe->draw, llvmpipe->setup); + } + else { + lp_init_vbuf(llvmpipe); + } + + /* plug in AA line/point stages */ + draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe); + draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe); + +#if USE_DRAW_STAGE_PSTIPPLE + /* Do polygon stipple w/ texture map + frag prog? */ + draw_install_pstipple_stage(llvmpipe->draw, &llvmpipe->pipe); +#endif + + lp_init_surface_functions(llvmpipe); + + return &llvmpipe->pipe; + + fail: + llvmpipe_destroy(&llvmpipe->pipe); + return NULL; +} + diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h new file mode 100644 index 0000000000..32b1925b77 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -0,0 +1,168 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_CONTEXT_H +#define SP_CONTEXT_H + +#include "pipe/p_context.h" + +#include "draw/draw_vertex.h" + +#include "lp_quad_pipe.h" +#include "lp_tex_sample.h" + + +/** + * This is a temporary variable for testing draw-stage polygon stipple. + * If zero, do stipple in lp_quad_stipple.c + */ +#define USE_DRAW_STAGE_PSTIPPLE 1 + +/* Number of threads working on individual quads. + * Setting to 1 disables this feature. + */ +#define SP_NUM_QUAD_THREADS 1 + +struct llvmpipe_vbuf_render; +struct draw_context; +struct draw_stage; +struct llvmpipe_tile_cache; +struct lp_fragment_shader; +struct lp_vertex_shader; + + +struct llvmpipe_context { + struct pipe_context pipe; /**< base class */ + + /** Constant state objects */ + const struct pipe_blend_state *blend; + const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct pipe_depth_stencil_alpha_state *depth_stencil; + const struct pipe_rasterizer_state *rasterizer; + const struct lp_fragment_shader *fs; + const struct lp_vertex_shader *vs; + + /** Other rendering state */ + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; + + unsigned num_samplers; + unsigned num_textures; + unsigned num_vertex_elements; + unsigned num_vertex_buffers; + + unsigned dirty; /**< Mask of SP_NEW_x flags */ + + /* Counter for occlusion queries. Note this supports overlapping + * queries. + */ + uint64_t occlusion_count; + unsigned active_query_count; + + /** Mapped vertex buffers */ + ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; + + /** Mapped constant buffers */ + void *mapped_constants[PIPE_SHADER_TYPES]; + + /** Vertex format */ + struct vertex_info vertex_info; + struct vertex_info vertex_info_vbuf; + + /** Which vertex shader output slot contains point size */ + int psize_slot; + + unsigned reduced_api_prim; /**< PIPE_PRIM_POINTS, _LINES or _TRIANGLES */ + + /** Derived from scissor and surface bounds: */ + struct pipe_scissor_state cliprect; + + unsigned line_stipple_counter; + + /** Software quad rendering pipeline */ + struct { + struct quad_stage *polygon_stipple; + struct quad_stage *earlyz; + struct quad_stage *shade; + struct quad_stage *alpha_test; + struct quad_stage *stencil_test; + struct quad_stage *depth_test; + struct quad_stage *occlusion; + struct quad_stage *coverage; + struct quad_stage *blend; + struct quad_stage *colormask; + struct quad_stage *output; + + struct quad_stage *first; /**< points to one of the above stages */ + } quad[SP_NUM_QUAD_THREADS]; + + /** TGSI exec things */ + struct { + struct lp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS]; + struct lp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS]; + struct lp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS]; + struct lp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS]; + } tgsi; + + /** The primitive drawing context */ + struct draw_context *draw; + struct draw_stage *setup; + struct draw_stage *vbuf; + struct llvmpipe_vbuf_render *vbuf_render; + + boolean dirty_render_cache; + + struct llvmpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS]; + struct llvmpipe_tile_cache *zsbuf_cache; + + struct llvmpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; + + unsigned use_sse : 1; + unsigned dump_fs : 1; + unsigned no_rast : 1; +}; + + +static INLINE struct llvmpipe_context * +llvmpipe_context( struct pipe_context *pipe ) +{ + return (struct llvmpipe_context *)pipe; +} + +#endif /* SP_CONTEXT_H */ + diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c new file mode 100644 index 0000000000..87e8623c4f --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -0,0 +1,194 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Brian Paul + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/internal/p_winsys_screen.h" +#include "pipe/p_inlines.h" +#include "util/u_prim.h" + +#include "lp_context.h" +#include "lp_state.h" + +#include "draw/draw_context.h" + + + +static void +llvmpipe_map_constant_buffers(struct llvmpipe_context *lp) +{ + struct pipe_winsys *ws = lp->pipe.winsys; + uint i, size; + + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + if (lp->constants[i].buffer && lp->constants[i].buffer->size) + lp->mapped_constants[i] = ws->buffer_map(ws, lp->constants[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + } + + if (lp->constants[PIPE_SHADER_VERTEX].buffer) + size = lp->constants[PIPE_SHADER_VERTEX].buffer->size; + else + size = 0; + + draw_set_mapped_constant_buffer(lp->draw, + lp->mapped_constants[PIPE_SHADER_VERTEX], + size); +} + + +static void +llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp) +{ + struct pipe_winsys *ws = lp->pipe.winsys; + uint i; + + /* really need to flush all prims since the vert/frag shaders const buffers + * are going away now. + */ + draw_flush(lp->draw); + + draw_set_mapped_constant_buffer(lp->draw, NULL, 0); + + for (i = 0; i < 2; i++) { + if (lp->constants[i].buffer && lp->constants[i].buffer->size) + ws->buffer_unmap(ws, lp->constants[i].buffer); + lp->mapped_constants[i] = NULL; + } +} + + +boolean +llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count) +{ + return llvmpipe_draw_elements(pipe, NULL, 0, mode, start, count); +} + + +/** + * Draw vertex arrays, with optional indexing. + * Basically, map the vertex buffers (and drawing surfaces), then hand off + * the drawing to the 'draw' module. + */ +boolean +llvmpipe_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned min_index, + unsigned max_index, + unsigned mode, unsigned start, unsigned count) +{ + struct llvmpipe_context *lp = llvmpipe_context(pipe); + struct draw_context *draw = lp->draw; + unsigned i; + + lp->reduced_api_prim = u_reduced_prim(mode); + + if (lp->dirty) + llvmpipe_update_derived( lp ); + + llvmpipe_map_transfers(lp); + llvmpipe_map_constant_buffers(lp); + + /* + * Map vertex buffers + */ + for (i = 0; i < lp->num_vertex_buffers; i++) { + void *buf + = pipe_buffer_map(pipe->screen, + lp->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); + } + + /* Map index buffer, if present */ + if (indexBuffer) { + void *mapped_indexes + = pipe_buffer_map(pipe->screen, indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer_range(draw, indexSize, + min_index, + max_index, + mapped_indexes); + } + else { + /* no index/element buffer */ + draw_set_mapped_element_buffer_range(draw, 0, start, + start + count - 1, NULL); + } + + /* draw! */ + draw_arrays(draw, mode, start, count); + + /* + * unmap vertex/index buffers - will cause draw module to flush + */ + for (i = 0; i < lp->num_vertex_buffers; i++) { + draw_set_mapped_vertex_buffer(draw, i, NULL); + pipe_buffer_unmap(pipe->screen, lp->vertex_buffer[i].buffer); + } + if (indexBuffer) { + draw_set_mapped_element_buffer(draw, 0, NULL); + pipe_buffer_unmap(pipe->screen, indexBuffer); + } + + + /* Note: leave drawing surfaces mapped */ + llvmpipe_unmap_constant_buffers(lp); + + lp->dirty_render_cache = TRUE; + + return TRUE; +} + + +boolean +llvmpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + return llvmpipe_draw_range_elements( pipe, indexBuffer, + indexSize, + 0, 0xffffffff, + mode, start, count ); +} + + +void +llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags) +{ + struct llvmpipe_context *lp = llvmpipe_context(pipe); + draw_set_edgeflags(lp->draw, edgeflags); +} diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c new file mode 100644 index 0000000000..2bb6414b3f --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -0,0 +1,94 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "draw/draw_context.h" +#include "lp_flush.h" +#include "lp_context.h" +#include "lp_surface.h" +#include "lp_state.h" +#include "lp_tile_cache.h" +#include "lp_winsys.h" + + +void +llvmpipe_flush( struct pipe_context *pipe, + unsigned flags, + struct pipe_fence_handle **fence ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + uint i; + + draw_flush(llvmpipe->draw); + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + for (i = 0; i < llvmpipe->num_textures; i++) { + lp_flush_tile_cache(llvmpipe, llvmpipe->tex_cache[i]); + } + } + + if (flags & PIPE_FLUSH_RENDER_CACHE) { + for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) + if (llvmpipe->cbuf_cache[i]) + lp_flush_tile_cache(llvmpipe, llvmpipe->cbuf_cache[i]); + + if (llvmpipe->zsbuf_cache) + lp_flush_tile_cache(llvmpipe, llvmpipe->zsbuf_cache); + + /* Need this call for hardware buffers before swapbuffers. + * + * there should probably be another/different flush-type function + * that's called before swapbuffers because we don't always want + * to unmap surfaces when flushing. + */ + llvmpipe_unmap_transfers(llvmpipe); + + llvmpipe->dirty_render_cache = FALSE; + } + + /* Enable to dump BMPs of the color/depth buffers each frame */ +#if 0 + if(flags & PIPE_FLUSH_FRAME) { + static unsigned frame_no = 1; + static char filename[256]; + util_snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no); + debug_dump_surface_bmp(filename, llvmpipe->framebuffer.cbufs[0]); + util_snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no); + debug_dump_surface_bmp(filename, llvmpipe->framebuffer.zsbuf); + ++frame_no; + } +#endif + + if (fence) + *fence = NULL; +} + diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h new file mode 100644 index 0000000000..787bc5f2b2 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_flush.h @@ -0,0 +1,37 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_FLUSH_H +#define SP_FLUSH_H + +struct pipe_context; +struct pipe_fence_handle; + +void llvmpipe_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence); + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_fs.h b/src/gallium/drivers/llvmpipe/lp_fs.h new file mode 100644 index 0000000000..408167075a --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_fs.h @@ -0,0 +1,54 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_FS_H +#define SP_FS_H + +struct lp_fragment_shader * +llvmpipe_create_fs_exec(struct llvmpipe_context *llvmpipe, + const struct pipe_shader_state *templ); + +struct lp_fragment_shader * +llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe, + const struct pipe_shader_state *templ); + +struct lp_fragment_shader * +llvmpipe_create_fs_llvm(struct llvmpipe_context *llvmpipe, + const struct pipe_shader_state *templ); + +struct tgsi_interp_coef; +struct tgsi_exec_vector; + +void lp_setup_pos_vector(const struct tgsi_interp_coef *coef, + float x, float y, + struct tgsi_exec_vector *quadpos); + + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_fs_exec.c b/src/gallium/drivers/llvmpipe/lp_fs_exec.c new file mode 100644 index 0000000000..ea85697fe2 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_fs_exec.c @@ -0,0 +1,162 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Execute fragment shader using the TGSI interpreter. + */ + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_fs.h" +#include "lp_quad.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_parse.h" + + +/** + * Subclass of lp_fragment_shader + */ +struct lp_exec_fragment_shader +{ + struct lp_fragment_shader base; + /* No other members for now */ +}; + + +/** cast wrapper */ +static INLINE struct lp_exec_fragment_shader * +lp_exec_fragment_shader(const struct lp_fragment_shader *base) +{ + return (struct lp_exec_fragment_shader *) base; +} + + +/** + * Compute quad X,Y,Z,W for the four fragments in a quad. + * + * This should really be part of the compiled shader. + */ +void +lp_setup_pos_vector(const struct tgsi_interp_coef *coef, + float x, float y, + struct tgsi_exec_vector *quadpos) +{ + uint chan; + /* do X */ + quadpos->xyzw[0].f[0] = x; + quadpos->xyzw[0].f[1] = x + 1; + quadpos->xyzw[0].f[2] = x; + quadpos->xyzw[0].f[3] = x + 1; + + /* do Y */ + quadpos->xyzw[1].f[0] = y; + quadpos->xyzw[1].f[1] = y; + quadpos->xyzw[1].f[2] = y + 1; + quadpos->xyzw[1].f[3] = y + 1; + + /* do Z and W for all fragments in the quad */ + for (chan = 2; chan < 4; chan++) { + const float dadx = coef->dadx[chan]; + const float dady = coef->dady[chan]; + const float a0 = coef->a0[chan] + dadx * x + dady * y; + quadpos->xyzw[chan].f[0] = a0; + quadpos->xyzw[chan].f[1] = a0 + dadx; + quadpos->xyzw[chan].f[2] = a0 + dady; + quadpos->xyzw[chan].f[3] = a0 + dadx + dady; + } +} + + +static void +exec_prepare( const struct lp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct tgsi_sampler **samplers ) +{ + /* + * Bind tokens/shader to the interpreter's machine state. + * Avoid redundant binding. + */ + if (machine->Tokens != base->shader.tokens) { + tgsi_exec_machine_bind_shader( machine, + base->shader.tokens, + PIPE_MAX_SAMPLERS, + samplers ); + } +} + + +/* TODO: hide the machine struct in here somewhere, remove from this + * interface: + */ +static unsigned +exec_run( const struct lp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct quad_header *quad ) +{ + /* Compute X, Y, Z, W vals for this quad */ + lp_setup_pos_vector(quad->posCoef, + (float)quad->input.x0, (float)quad->input.y0, + &machine->QuadPos); + + return tgsi_exec_machine_run( machine ); +} + + +static void +exec_delete( struct lp_fragment_shader *base ) +{ + FREE((void *) base->shader.tokens); + FREE(base); +} + + +struct lp_fragment_shader * +llvmpipe_create_fs_exec(struct llvmpipe_context *llvmpipe, + const struct pipe_shader_state *templ) +{ + struct lp_exec_fragment_shader *shader; + + /* Decide whether we'll be codegenerating this shader and if so do + * that now. + */ + + shader = CALLOC_STRUCT(lp_exec_fragment_shader); + if (!shader) + return NULL; + + /* we need to keep a local copy of the tokens */ + shader->base.shader.tokens = tgsi_dup_tokens(templ->tokens); + shader->base.prepare = exec_prepare; + shader->base.run = exec_run; + shader->base.delete = exec_delete; + + return &shader->base; +} diff --git a/src/gallium/drivers/llvmpipe/lp_fs_llvm.c b/src/gallium/drivers/llvmpipe/lp_fs_llvm.c new file mode 100644 index 0000000000..8c186badb4 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_fs_llvm.c @@ -0,0 +1,205 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Execute fragment shader using LLVM code generation. + * Authors: + * Zack Rusin + */ + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_fs.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "tgsi/tgsi_sse2.h" + +#if 0 + +/** + * Subclass of lp_fragment_shader + */ +struct lp_llvm_fragment_shader +{ + struct lp_fragment_shader base; + struct gallivm_prog *llvm_prog; +}; + + +static void +shade_quad_llvm(struct quad_stage *qs, + struct quad_header *quad) +{ + struct quad_shade_stage *qss = quad_shade_stage(qs); + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + float dests[4][16][4] ALIGN16_ATTRIB; + float inputs[4][16][4] ALIGN16_ATTRIB; + const float fx = (float) quad->x0; + const float fy = (float) quad->y0; + struct gallivm_prog *llvm = qss->llvm_prog; + + inputs[0][0][0] = fx; + inputs[1][0][0] = fx + 1.0f; + inputs[2][0][0] = fx; + inputs[3][0][0] = fx + 1.0f; + + inputs[0][0][1] = fy; + inputs[1][0][1] = fy; + inputs[2][0][1] = fy + 1.0f; + inputs[3][0][1] = fy + 1.0f; + + + gallivm_prog_inputs_interpolate(llvm, inputs, quad->coef); + +#if DLLVM + debug_printf("MASK = %d\n", quad->mask); + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 2; ++j) { + debug_printf("IN(%d,%d) [%f %f %f %f]\n", i, j, + inputs[i][j][0], inputs[i][j][1], inputs[i][j][2], inputs[i][j][3]); + } + } +#endif + + quad->mask &= + gallivm_fragment_shader_exec(llvm, fx, fy, dests, inputs, + llvmpipe->mapped_constants[PIPE_SHADER_FRAGMENT], + qss->samplers); +#if DLLVM + debug_printf("OUT LLVM = 1[%f %f %f %f], 2[%f %f %f %f]\n", + dests[0][0][0], dests[0][0][1], dests[0][0][2], dests[0][0][3], + dests[0][1][0], dests[0][1][1], dests[0][1][2], dests[0][1][3]); +#endif + + /* store result color */ + if (qss->colorOutSlot >= 0) { + unsigned i; + /* XXX need to handle multiple color outputs someday */ + allvmrt(qss->stage.llvmpipe->fs->info.output_semantic_name[qss->colorOutSlot] + == TGSI_SEMANTIC_COLOR); + for (i = 0; i < QUAD_SIZE; ++i) { + quad->outputs.color[0][0][i] = dests[i][qss->colorOutSlot][0]; + quad->outputs.color[0][1][i] = dests[i][qss->colorOutSlot][1]; + quad->outputs.color[0][2][i] = dests[i][qss->colorOutSlot][2]; + quad->outputs.color[0][3][i] = dests[i][qss->colorOutSlot][3]; + } + } +#if DLLVM + for (int i = 0; i < QUAD_SIZE; ++i) { + debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot, + quad->outputs.color[0][0][i], + quad->outputs.color[0][1][i], + quad->outputs.color[0][2][i], + quad->outputs.color[0][3][i]); + } +#endif + + /* store result Z */ + if (qss->depthOutSlot >= 0) { + /* output[slot] is new Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = dests[i][0][2]; + } + } + else { + /* copy input Z (which was interpolated by the executor) to output Z */ + uint i; + for (i = 0; i < 4; i++) { + quad->outputs.depth[i] = inputs[i][0][2]; + } + } +#if DLLVM + debug_printf("D [%f, %f, %f, %f] mask = %d\n", + quad->outputs.depth[0], + quad->outputs.depth[1], + quad->outputs.depth[2], + quad->outputs.depth[3], quad->mask); +#endif + + /* shader may cull fragments */ + if( quad->mask ) { + qs->next->run( qs->next, quad ); + } +} + + +unsigned +run_llvm_fs( const struct lp_fragment_shader *base, + struct foo *machine ) +{ +} + + +void +delete_llvm_fs( struct lp_fragment_shader *base ) +{ + FREE(base); +} + + +struct lp_fragment_shader * +llvmpipe_create_fs_llvm(struct llvmpipe_context *llvmpipe, + const struct pipe_shader_state *templ) +{ + struct lp_llvm_fragment_shader *shader = NULL; + + /* LLVM fragment shaders currently disabled: + */ + state = CALLOC_STRUCT(lp_llvm_shader_state); + if (!state) + return NULL; + + state->llvm_prog = 0; + + if (!gallivm_global_cpu_engine()) { + gallivm_cpu_engine_create(state->llvm_prog); + } + else + gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); + + if (shader) { + shader->base.run = run_llvm_fs; + shader->base.delete = delete_llvm_fs; + } + + return shader; +} + + +#else + +struct lp_fragment_shader * +llvmpipe_create_fs_llvm(struct llvmpipe_context *llvmpipe, + const struct pipe_shader_state *templ) +{ + return NULL; +} + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_fs_sse.c b/src/gallium/drivers/llvmpipe/lp_fs_sse.c new file mode 100644 index 0000000000..61c40dd4b3 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_fs_sse.c @@ -0,0 +1,169 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Execute fragment shader using runtime SSE code generation. + */ + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_fs.h" +#include "lp_quad.h" + +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_sse2.h" + + +#if defined(PIPE_ARCH_X86) + +#include "rtasm/rtasm_x86sse.h" + + + +/** + * Subclass of lp_fragment_shader + */ +struct lp_sse_fragment_shader +{ + struct lp_fragment_shader base; + struct x86_function sse2_program; + tgsi_sse2_fs_function func; + float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; +}; + + +/** cast wrapper */ +static INLINE struct lp_sse_fragment_shader * +lp_sse_fragment_shader(const struct lp_fragment_shader *base) +{ + return (struct lp_sse_fragment_shader *) base; +} + + +static void +fs_sse_prepare( const struct lp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct tgsi_sampler **samplers ) +{ + machine->Samplers = samplers; +} + + +/* TODO: codegenerate the whole run function, skip this wrapper. + * TODO: break dependency on tgsi_exec_machine struct + * TODO: push Position calculation into the generated shader + * TODO: process >1 quad at a time + */ +static unsigned +fs_sse_run( const struct lp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct quad_header *quad ) +{ + struct lp_sse_fragment_shader *shader = lp_sse_fragment_shader(base); + + /* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */ + lp_setup_pos_vector(quad->posCoef, + (float)quad->input.x0, (float)quad->input.y0, + machine->Temps); + + /* init kill mask */ + tgsi_set_kill_mask(machine, 0x0); + tgsi_set_exec_mask(machine, 1, 1, 1, 1); + + shader->func( machine, + machine->Consts, + (const float (*)[4])shader->immediates, + machine->InterpCoefs + // , &machine->QuadPos + ); + + return ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]); +} + + +static void +fs_sse_delete( struct lp_fragment_shader *base ) +{ + struct lp_sse_fragment_shader *shader = lp_sse_fragment_shader(base); + + x86_release_func( &shader->sse2_program ); + FREE(shader); +} + + +struct lp_fragment_shader * +llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe, + const struct pipe_shader_state *templ) +{ + struct lp_sse_fragment_shader *shader; + + if (!llvmpipe->use_sse) + return NULL; + + shader = CALLOC_STRUCT(lp_sse_fragment_shader); + if (!shader) + return NULL; + + x86_init_func( &shader->sse2_program ); + + if (!tgsi_emit_sse2( templ->tokens, &shader->sse2_program, + shader->immediates, FALSE )) { + FREE(shader); + return NULL; + } + + shader->func = (tgsi_sse2_fs_function) x86_get_func( &shader->sse2_program ); + if (!shader->func) { + x86_release_func( &shader->sse2_program ); + FREE(shader); + return NULL; + } + + shader->base.shader.tokens = NULL; /* don't hold reference to templ->tokens */ + shader->base.prepare = fs_sse_prepare; + shader->base.run = fs_sse_run; + shader->base.delete = fs_sse_delete; + + return &shader->base; +} + + +#else + +/* Maybe put this variant in the header file. + */ +struct lp_fragment_shader * +llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe, + const struct pipe_shader_state *templ) +{ + return NULL; +} + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_prim_setup.c b/src/gallium/drivers/llvmpipe/lp_prim_setup.c new file mode 100644 index 0000000000..5a5a617500 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_prim_setup.c @@ -0,0 +1,190 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief A draw stage that drives our triangle setup routines from + * within the draw pipeline. One of two ways to drive setup, the + * other being in lp_prim_vbuf.c. + * + * \author Keith Whitwell + * \author Brian Paul + */ + + +#include "lp_context.h" +#include "lp_setup.h" +#include "lp_state.h" +#include "lp_prim_setup.h" +#include "draw/draw_pipe.h" +#include "draw/draw_vertex.h" +#include "util/u_memory.h" + +/** + * Triangle setup info (derived from draw_stage). + * Also used for line drawing (taking some liberties). + */ +struct setup_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct setup_context *setup; +}; + + + +/** + * Basically a cast wrapper. + */ +static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) +{ + return (struct setup_stage *)stage; +} + + +typedef const float (*cptrf4)[4]; + +static void +do_tri(struct draw_stage *stage, struct prim_header *prim) +{ + struct setup_stage *setup = setup_stage( stage ); + + setup_tri( setup->setup, + (cptrf4)prim->v[0]->data, + (cptrf4)prim->v[1]->data, + (cptrf4)prim->v[2]->data ); +} + +static void +do_line(struct draw_stage *stage, struct prim_header *prim) +{ + struct setup_stage *setup = setup_stage( stage ); + + setup_line( setup->setup, + (cptrf4)prim->v[0]->data, + (cptrf4)prim->v[1]->data ); +} + +static void +do_point(struct draw_stage *stage, struct prim_header *prim) +{ + struct setup_stage *setup = setup_stage( stage ); + + setup_point( setup->setup, + (cptrf4)prim->v[0]->data ); +} + + + + +static void setup_begin( struct draw_stage *stage ) +{ + struct setup_stage *setup = setup_stage(stage); + + setup_prepare( setup->setup ); + + stage->point = do_point; + stage->line = do_line; + stage->tri = do_tri; +} + + +static void setup_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + setup_begin(stage); + stage->point( stage, header ); +} + +static void setup_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + setup_begin(stage); + stage->line( stage, header ); +} + + +static void setup_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + setup_begin(stage); + stage->tri( stage, header ); +} + + + +static void setup_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->point = setup_first_point; + stage->line = setup_first_line; + stage->tri = setup_first_tri; +} + + +static void reset_stipple_counter( struct draw_stage *stage ) +{ +} + + +static void render_destroy( struct draw_stage *stage ) +{ + struct setup_stage *ssetup = setup_stage(stage); + setup_destroy_context(ssetup->setup); + FREE( stage ); +} + + +/** + * Create a new primitive setup/render stage. + */ +struct draw_stage *lp_draw_render_stage( struct llvmpipe_context *llvmpipe ) +{ + struct setup_stage *sstage = CALLOC_STRUCT(setup_stage); + + sstage->setup = setup_create_context(llvmpipe); + sstage->stage.draw = llvmpipe->draw; + sstage->stage.point = setup_first_point; + sstage->stage.line = setup_first_line; + sstage->stage.tri = setup_first_tri; + sstage->stage.flush = setup_flush; + sstage->stage.reset_stipple_counter = reset_stipple_counter; + sstage->stage.destroy = render_destroy; + + return (struct draw_stage *)sstage; +} + +struct setup_context * +lp_draw_setup_context( struct draw_stage *stage ) +{ + struct setup_stage *ssetup = setup_stage(stage); + return ssetup->setup; +} + +void +lp_draw_flush( struct draw_stage *stage ) +{ + stage->flush( stage, 0 ); +} diff --git a/src/gallium/drivers/llvmpipe/lp_prim_setup.h b/src/gallium/drivers/llvmpipe/lp_prim_setup.h new file mode 100644 index 0000000000..9cd3439660 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_prim_setup.h @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef SP_PRIM_SETUP_H +#define SP_PRIM_SETUP_H + + +/** + * vbuf is a special stage to gather the stream of triangles, lines, points + * together and reconstruct vertex buffers for hardware upload. + * + * First attempt, work in progress. + * + * TODO: + * - separate out vertex buffer building and primitive emit, ie >1 draw per vb. + * - tell vbuf stage how to build hw vertices directly + * - pass vbuf stage a buffer pointer for direct emit to agp/vram. + * + * + * + * Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + + +struct draw_stage; +struct llvmpipe_context; + + +typedef void (*vbuf_draw_func)( struct pipe_context *pipe, + unsigned prim, + const ushort *elements, + unsigned nr_elements, + const void *vertex_buffer, + unsigned nr_vertices ); + + +extern struct draw_stage * +lp_draw_render_stage( struct llvmpipe_context *llvmpipe ); + +extern struct setup_context * +lp_draw_setup_context( struct draw_stage * ); + +extern void +lp_draw_flush( struct draw_stage * ); + + +extern struct draw_stage * +lp_draw_vbuf_stage( struct draw_context *draw_context, + struct pipe_context *pipe, + vbuf_draw_func draw ); + + +#endif /* SP_PRIM_SETUP_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c new file mode 100644 index 0000000000..e6d9e375a3 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c @@ -0,0 +1,585 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Interface between 'draw' module's output and the llvmpipe rasterizer/setup + * code. When the 'draw' module has finished filling a vertex buffer, the + * draw_arrays() functions below will be called. Loop over the vertices and + * call the point/line/tri setup functions. + * + * Authors + * Brian Paul + */ + + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_prim_vbuf.h" +#include "lp_prim_setup.h" +#include "lp_setup.h" +#include "draw/draw_context.h" +#include "draw/draw_vbuf.h" +#include "util/u_memory.h" + + +#define SP_MAX_VBUF_INDEXES 1024 +#define SP_MAX_VBUF_SIZE 4096 + +typedef const float (*cptrf4)[4]; + +/** + * Subclass of vbuf_render. + */ +struct llvmpipe_vbuf_render +{ + struct vbuf_render base; + struct llvmpipe_context *llvmpipe; + uint prim; + uint vertex_size; + uint nr_vertices; + uint vertex_buffer_size; + void *vertex_buffer; +}; + + +/** cast wrapper */ +static struct llvmpipe_vbuf_render * +llvmpipe_vbuf_render(struct vbuf_render *vbr) +{ + return (struct llvmpipe_vbuf_render *) vbr; +} + + +static const struct vertex_info * +lp_vbuf_get_vertex_info(struct vbuf_render *vbr) +{ + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + return llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe); +} + + +static boolean +lp_vbuf_allocate_vertices(struct vbuf_render *vbr, + ushort vertex_size, ushort nr_vertices) +{ + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + unsigned size = vertex_size * nr_vertices; + + if (cvbr->vertex_buffer_size < size) { + align_free(cvbr->vertex_buffer); + cvbr->vertex_buffer = align_malloc(size, 16); + cvbr->vertex_buffer_size = size; + } + + cvbr->vertex_size = vertex_size; + cvbr->nr_vertices = nr_vertices; + + return cvbr->vertex_buffer != NULL; +} + +static void +lp_vbuf_release_vertices(struct vbuf_render *vbr) +{ +#if 0 + { + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + const struct vertex_info *info = + llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe); + const float *vtx = (const float *) cvbr->vertex_buffer; + uint i, j; + debug_printf("%s (vtx_size = %u, vtx_used = %u)\n", + __FUNCTION__, cvbr->vertex_size, cvbr->nr_vertices); + for (i = 0; i < cvbr->nr_vertices; i++) { + for (j = 0; j < info->num_attribs; j++) { + uint k; + switch (info->attrib[j].emit) { + case EMIT_4F: k = 4; break; + case EMIT_3F: k = 3; break; + case EMIT_2F: k = 2; break; + case EMIT_1F: k = 1; break; + default: assert(0); + } + debug_printf("Vert %u attr %u: ", i, j); + while (k-- > 0) { + debug_printf("%g ", vtx[0]); + vtx++; + } + debug_printf("\n"); + } + } + } +#endif + + /* keep the old allocation for next time */ +} + +static void * +lp_vbuf_map_vertices(struct vbuf_render *vbr) +{ + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + return cvbr->vertex_buffer; +} + +static void +lp_vbuf_unmap_vertices(struct vbuf_render *vbr, + ushort min_index, + ushort max_index ) +{ + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size ); + /* do nothing */ +} + + +static boolean +lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) +{ + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + + /* XXX: break this dependency - make setup_context live under + * llvmpipe, rename the old "setup" draw stage to something else. + */ + struct setup_context *setup_ctx = lp_draw_setup_context(cvbr->llvmpipe->setup); + + setup_prepare( setup_ctx ); + + cvbr->prim = prim; + return TRUE; + +} + + +static INLINE cptrf4 get_vert( const void *vertex_buffer, + int index, + int stride ) +{ + return (cptrf4)((char *)vertex_buffer + index * stride); +} + + +/** + * draw elements / indexed primitives + */ +static void +lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) +{ + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + struct llvmpipe_context *llvmpipe = cvbr->llvmpipe; + const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float); + const void *vertex_buffer = cvbr->vertex_buffer; + unsigned i; + + /* XXX: break this dependency - make setup_context live under + * llvmpipe, rename the old "setup" draw stage to something else. + */ + struct draw_stage *setup = llvmpipe->setup; + struct setup_context *setup_ctx = lp_draw_setup_context(setup); + + switch (cvbr->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < nr; i++) { + setup_point( setup_ctx, + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 1; i < nr; i += 2) { + setup_line( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < nr; i ++) { + setup_line( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + break; + + case PIPE_PRIM_LINE_LOOP: + for (i = 1; i < nr; i ++) { + setup_line( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + if (nr) { + setup_line( setup_ctx, + get_vert(vertex_buffer, indices[nr-1], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } + break; + + case PIPE_PRIM_TRIANGLES: + for (i = 2; i < nr; i += 3) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + for (i = 2; i < nr; i += 1) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i+(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-(i&1)], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i+(i&1)-2], stride), + get_vert(vertex_buffer, indices[i-(i&1)-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + for (i = 2; i < nr; i += 1) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_QUADS: + for (i = 3; i < nr; i += 4) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + for (i = 3; i < nr; i += 2) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride)); + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + break; + + case PIPE_PRIM_POLYGON: + /* Almost same as tri fan but the _first_ vertex specifies the flat + * shading color. Note that the first polygon vertex is passed as + * the last triangle vertex here. + * flatshade_first state makes no difference. + */ + for (i = 2; i < nr; i += 1) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } + break; + + default: + assert(0); + } + + /* XXX: why are we calling this??? If we had to call something, it + * would be a function in lp_setup.c: + */ + lp_draw_flush( setup ); +} + + +/** + * This function is hit when the draw module is working in pass-through mode. + * It's up to us to convert the vertex array into point/line/tri prims. + */ +static void +lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) +{ + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + struct llvmpipe_context *llvmpipe = cvbr->llvmpipe; + const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float); + const void *vertex_buffer = + (void *) get_vert(cvbr->vertex_buffer, start, stride); + unsigned i; + + /* XXX: break this dependency - make setup_context live under + * llvmpipe, rename the old "setup" draw stage to something else. + */ + struct draw_stage *setup = llvmpipe->setup; + struct setup_context *setup_ctx = lp_draw_setup_context(setup); + + switch (cvbr->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < nr; i++) { + setup_point( setup_ctx, + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINES: + for (i = 1; i < nr; i += 2) { + setup_line( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINE_STRIP: + for (i = 1; i < nr; i ++) { + setup_line( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + break; + + case PIPE_PRIM_LINE_LOOP: + for (i = 1; i < nr; i ++) { + setup_line( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + if (nr) { + setup_line( setup_ctx, + get_vert(vertex_buffer, nr-1, stride), + get_vert(vertex_buffer, 0, stride) ); + } + break; + + case PIPE_PRIM_TRIANGLES: + for (i = 2; i < nr; i += 3) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-2, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + for (i = 2; i < nr; i++) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i+(i&1)-1, stride), + get_vert(vertex_buffer, i-(i&1), stride), + get_vert(vertex_buffer, i-2, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i+(i&1)-2, stride), + get_vert(vertex_buffer, i-(i&1)-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + for (i = 2; i < nr; i += 1) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_QUADS: + for (i = 3; i < nr; i += 4) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + for (i = 3; i < nr; i += 2) { + if (llvmpipe->rasterizer->flatshade_first) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + else { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + break; + + case PIPE_PRIM_POLYGON: + /* Almost same as tri fan but the _first_ vertex specifies the flat + * shading color. Note that the first polygon vertex is passed as + * the last triangle vertex here. + * flatshade_first state makes no difference. + */ + for (i = 2; i < nr; i += 1) { + setup_tri( setup_ctx, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride) ); + } + break; + + default: + assert(0); + } +} + + + +static void +lp_vbuf_destroy(struct vbuf_render *vbr) +{ + struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr); + cvbr->llvmpipe->vbuf_render = NULL; + FREE(cvbr); +} + + +/** + * Initialize the post-transform vertex buffer information for the given + * context. + */ +void +lp_init_vbuf(struct llvmpipe_context *lp) +{ + assert(lp->draw); + + lp->vbuf_render = CALLOC_STRUCT(llvmpipe_vbuf_render); + + lp->vbuf_render->base.max_indices = SP_MAX_VBUF_INDEXES; + lp->vbuf_render->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE; + + lp->vbuf_render->base.get_vertex_info = lp_vbuf_get_vertex_info; + lp->vbuf_render->base.allocate_vertices = lp_vbuf_allocate_vertices; + lp->vbuf_render->base.map_vertices = lp_vbuf_map_vertices; + lp->vbuf_render->base.unmap_vertices = lp_vbuf_unmap_vertices; + lp->vbuf_render->base.set_primitive = lp_vbuf_set_primitive; + lp->vbuf_render->base.draw = lp_vbuf_draw; + lp->vbuf_render->base.draw_arrays = lp_vbuf_draw_arrays; + lp->vbuf_render->base.release_vertices = lp_vbuf_release_vertices; + lp->vbuf_render->base.destroy = lp_vbuf_destroy; + + lp->vbuf_render->llvmpipe = lp; + + lp->vbuf = draw_vbuf_stage(lp->draw, &lp->vbuf_render->base); + + draw_set_rasterize_stage(lp->draw, lp->vbuf); + + draw_set_render(lp->draw, &lp->vbuf_render->base); +} diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h new file mode 100644 index 0000000000..6405c584b6 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_VBUF_H +#define SP_VBUF_H + + +struct llvmpipe_context; + +extern void +lp_init_vbuf(struct llvmpipe_context *llvmpipe); + + +#endif /* SP_VBUF_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_quad.h b/src/gallium/drivers/llvmpipe/lp_quad.h new file mode 100644 index 0000000000..bd6c6cb912 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad.h @@ -0,0 +1,106 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_QUAD_H +#define SP_QUAD_H + +#include "pipe/p_state.h" +#include "tgsi/tgsi_exec.h" + + +#define QUAD_PRIM_POINT 1 +#define QUAD_PRIM_LINE 2 +#define QUAD_PRIM_TRI 3 + + +/* The rasterizer generates 2x2 quads of fragment and feeds them to + * the current fp_machine (see below). + * Remember that Y=0=top with Y increasing down the window. + */ +#define QUAD_TOP_LEFT 0 +#define QUAD_TOP_RIGHT 1 +#define QUAD_BOTTOM_LEFT 2 +#define QUAD_BOTTOM_RIGHT 3 + +#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT) +#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT) +#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT) +#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT) +#define MASK_ALL 0xf + + +/** + * Quad stage inputs (pos, coverage, front/back face, etc) + */ +struct quad_header_input +{ + int x0, y0; /**< quad window pos, always even */ + float coverage[QUAD_SIZE]; /**< fragment coverage for antialiasing */ + unsigned facing:1; /**< Front (0) or back (1) facing? */ + unsigned prim:2; /**< QUAD_PRIM_POINT, LINE, TRI */ +}; + + +/** + * Quad stage inputs/outputs. + */ +struct quad_header_inout +{ + unsigned mask:4; +}; + + +/** + * Quad stage outputs (color & depth). + */ +struct quad_header_output +{ + /** colors in SOA format (rrrr, gggg, bbbb, aaaa) */ + float color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE]; + float depth[QUAD_SIZE]; +}; + + +/** + * Encodes everything we need to know about a 2x2 pixel block. Uses + * "Channel-Serial" or "SoA" layout. + */ +struct quad_header { + struct quad_header_input input; + struct quad_header_inout inout; + struct quad_header_output output; + + const struct tgsi_interp_coef *coef; + const struct tgsi_interp_coef *posCoef; + + unsigned nr_attrs; +}; + +#endif /* SP_QUAD_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_quad_alpha_test.c b/src/gallium/drivers/llvmpipe/lp_quad_alpha_test.c new file mode 100644 index 0000000000..eea4ef9c85 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_alpha_test.c @@ -0,0 +1,108 @@ + +/** + * quad alpha test + */ + +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_quad_pipe.h" +#include "pipe/p_defines.h" +#include "util/u_memory.h" + + +static void +alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + const float ref = llvmpipe->depth_stencil->alpha.ref_value; + unsigned passMask = 0x0, j; + const uint cbuf = 0; /* only output[0].alpha is tested */ + const float *aaaa = quad->output.color[cbuf][3]; + + switch (llvmpipe->depth_stencil->alpha.func) { + case PIPE_FUNC_NEVER: + break; + case PIPE_FUNC_LESS: + /* + * If mask were an array [4] we could do this SIMD-style: + * passMask = (quad->outputs.color[0][3] <= vec4(ref)); + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] < ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] == ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] <= ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] > ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] != ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (aaaa[j] >= ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_ALWAYS: + passMask = MASK_ALL; + break; + default: + assert(0); + } + + quad->inout.mask &= passMask; + + if (quad->inout.mask) + qs->next->run(qs->next, quad); +} + + +static void alpha_test_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void alpha_test_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage * +lp_quad_alpha_test_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = alpha_test_begin; + stage->run = alpha_test_quad; + stage->destroy = alpha_test_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_blend.c b/src/gallium/drivers/llvmpipe/lp_quad_blend.c new file mode 100644 index 0000000000..b281d7641b --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_blend.c @@ -0,0 +1,777 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * quad blending + * \author Brian Paul + */ + +#include "pipe/p_defines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_surface.h" +#include "lp_tile_cache.h" +#include "lp_quad_pipe.h" + + +#define VEC4_COPY(DST, SRC) \ +do { \ + DST[0] = SRC[0]; \ + DST[1] = SRC[1]; \ + DST[2] = SRC[2]; \ + DST[3] = SRC[3]; \ +} while(0) + +#define VEC4_SCALAR(DST, SRC) \ +do { \ + DST[0] = SRC; \ + DST[1] = SRC; \ + DST[2] = SRC; \ + DST[3] = SRC; \ +} while(0) + +#define VEC4_ADD(R, A, B) \ +do { \ + R[0] = A[0] + B[0]; \ + R[1] = A[1] + B[1]; \ + R[2] = A[2] + B[2]; \ + R[3] = A[3] + B[3]; \ +} while (0) + +#define VEC4_SUB(R, A, B) \ +do { \ + R[0] = A[0] - B[0]; \ + R[1] = A[1] - B[1]; \ + R[2] = A[2] - B[2]; \ + R[3] = A[3] - B[3]; \ +} while (0) + +/** Add and limit result to ceiling of 1.0 */ +#define VEC4_ADD_SAT(R, A, B) \ +do { \ + R[0] = A[0] + B[0]; if (R[0] > 1.0f) R[0] = 1.0f; \ + R[1] = A[1] + B[1]; if (R[1] > 1.0f) R[1] = 1.0f; \ + R[2] = A[2] + B[2]; if (R[2] > 1.0f) R[2] = 1.0f; \ + R[3] = A[3] + B[3]; if (R[3] > 1.0f) R[3] = 1.0f; \ +} while (0) + +/** Subtract and limit result to floor of 0.0 */ +#define VEC4_SUB_SAT(R, A, B) \ +do { \ + R[0] = A[0] - B[0]; if (R[0] < 0.0f) R[0] = 0.0f; \ + R[1] = A[1] - B[1]; if (R[1] < 0.0f) R[1] = 0.0f; \ + R[2] = A[2] - B[2]; if (R[2] < 0.0f) R[2] = 0.0f; \ + R[3] = A[3] - B[3]; if (R[3] < 0.0f) R[3] = 0.0f; \ +} while (0) + +#define VEC4_MUL(R, A, B) \ +do { \ + R[0] = A[0] * B[0]; \ + R[1] = A[1] * B[1]; \ + R[2] = A[2] * B[2]; \ + R[3] = A[3] * B[3]; \ +} while (0) + +#define VEC4_MIN(R, A, B) \ +do { \ + R[0] = (A[0] < B[0]) ? A[0] : B[0]; \ + R[1] = (A[1] < B[1]) ? A[1] : B[1]; \ + R[2] = (A[2] < B[2]) ? A[2] : B[2]; \ + R[3] = (A[3] < B[3]) ? A[3] : B[3]; \ +} while (0) + +#define VEC4_MAX(R, A, B) \ +do { \ + R[0] = (A[0] > B[0]) ? A[0] : B[0]; \ + R[1] = (A[1] > B[1]) ? A[1] : B[1]; \ + R[2] = (A[2] > B[2]) ? A[2] : B[2]; \ + R[3] = (A[3] > B[3]) ? A[3] : B[3]; \ +} while (0) + + + +static void +logicop_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) { + float dest[4][QUAD_SIZE]; + ubyte src[4][4], dst[4][4], res[4][4]; + uint *src4 = (uint *) src; + uint *dst4 = (uint *) dst; + uint *res4 = (uint *) res; + struct llvmpipe_cached_tile * + tile = lp_get_cached_tile(llvmpipe, + llvmpipe->cbuf_cache[cbuf], + quad->input.x0, quad->input.y0); + float (*quadColor)[4] = quad->output.color[cbuf]; + uint i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } + + /* convert to ubyte */ + for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */ + dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */ + dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */ + dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */ + dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */ + + src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */ + src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */ + src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */ + src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */ + } + + switch (llvmpipe->blend->logicop_func) { + case PIPE_LOGICOP_CLEAR: + for (j = 0; j < 4; j++) + res4[j] = 0; + break; + case PIPE_LOGICOP_NOR: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] | dst4[j]); + break; + case PIPE_LOGICOP_AND_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_COPY_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j]; + break; + case PIPE_LOGICOP_AND_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & ~dst4[j]; + break; + case PIPE_LOGICOP_INVERT: + for (j = 0; j < 4; j++) + res4[j] = ~dst4[j]; + break; + case PIPE_LOGICOP_XOR: + for (j = 0; j < 4; j++) + res4[j] = dst4[j] ^ src4[j]; + break; + case PIPE_LOGICOP_NAND: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] & dst4[j]); + break; + case PIPE_LOGICOP_AND: + for (j = 0; j < 4; j++) + res4[j] = src4[j] & dst4[j]; + break; + case PIPE_LOGICOP_EQUIV: + for (j = 0; j < 4; j++) + res4[j] = ~(src4[j] ^ dst4[j]); + break; + case PIPE_LOGICOP_NOOP: + for (j = 0; j < 4; j++) + res4[j] = dst4[j]; + break; + case PIPE_LOGICOP_OR_INVERTED: + for (j = 0; j < 4; j++) + res4[j] = ~src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_COPY: + for (j = 0; j < 4; j++) + res4[j] = src4[j]; + break; + case PIPE_LOGICOP_OR_REVERSE: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | ~dst4[j]; + break; + case PIPE_LOGICOP_OR: + for (j = 0; j < 4; j++) + res4[j] = src4[j] | dst4[j]; + break; + case PIPE_LOGICOP_SET: + for (j = 0; j < 4; j++) + res4[j] = ~0; + break; + default: + assert(0); + } + + for (j = 0; j < 4; j++) { + quadColor[j][0] = ubyte_to_float(res[j][0]); + quadColor[j][1] = ubyte_to_float(res[j][1]); + quadColor[j][2] = ubyte_to_float(res[j][2]); + quadColor[j][3] = ubyte_to_float(res[j][3]); + } + } + + /* pass quad to next stage */ + qs->next->run(qs->next, quad); +} + + + + +static void +blend_quad(struct quad_stage *qs, struct quad_header *quad) +{ + static const float zero[4] = { 0, 0, 0, 0 }; + static const float one[4] = { 1, 1, 1, 1 }; + + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + uint cbuf; + + if (llvmpipe->blend->logicop_enable) { + logicop_quad(qs, quad); + return; + } + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) { + float source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; + struct llvmpipe_cached_tile *tile + = lp_get_cached_tile(llvmpipe, + llvmpipe->cbuf_cache[cbuf], + quad->input.x0, quad->input.y0); + float (*quadColor)[4] = quad->output.color[cbuf]; + uint i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } + + /* + * Compute src/first term RGB + */ + switch (llvmpipe->blend->rgb_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[0], quadColor[0]); /* R */ + VEC4_COPY(source[1], quadColor[1]); /* G */ + VEC4_COPY(source[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const float *alpha = quadColor[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */ + VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */ + VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + { + const float *alpha = dest[3]; + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + { + const float *alpha = quadColor[3]; + float diff[4], temp[4]; + VEC4_SUB(diff, one, dest[3]); + VEC4_MIN(temp, alpha, diff); + VEC4_MUL(source[0], quadColor[0], temp); /* R */ + VEC4_MUL(source[1], quadColor[1], temp); /* G */ + VEC4_MUL(source[2], quadColor[2], temp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + float comp[4]; + VEC4_SCALAR(comp, llvmpipe->blend_color.color[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], comp); /* R */ + VEC4_SCALAR(comp, llvmpipe->blend_color.color[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], comp); /* G */ + VEC4_SCALAR(comp, llvmpipe->blend_color.color[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float alpha[4]; + VEC4_SCALAR(alpha, llvmpipe->blend_color.color[3]); + VEC4_MUL(source[0], quadColor[0], alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quadColor[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + float inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[0]); + VEC4_MUL(source[0], quadColor[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[1]); + VEC4_MUL(source[1], quadColor[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[2]); + VEC4_MUL(source[2], quadColor[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_alpha[4]; + VEC4_SCALAR(inv_alpha, 1.0f - llvmpipe->blend_color.color[3]); + VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + assert(0); /* to do */ + break; + default: + assert(0); + } + + /* + * Compute src/first term A + */ + switch (llvmpipe->blend->alpha_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[3], quadColor[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const float *alpha = quadColor[3]; + VEC4_MUL(source[3], quadColor[3], alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + /* multiply alpha by 1.0 */ + VEC4_COPY(source[3], quadColor[3]); /* A */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, llvmpipe->blend_color.color[3]); /* A */ + VEC4_MUL(source[3], quadColor[3], comp); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quadColor[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + /* A */ + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[3]); + VEC4_MUL(source[3], quadColor[3], inv_comp); + } + break; + default: + assert(0); + } + + + /* + * Compute dest/second term RGB + */ + switch (llvmpipe->blend->rgb_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */ + VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */ + VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */ + VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */ + VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(dest[0], dest[0], dest[0]); /* R */ + VEC4_MUL(dest[1], dest[1], dest[1]); /* G */ + VEC4_MUL(dest[2], dest[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + float comp[4]; + VEC4_SCALAR(comp, llvmpipe->blend_color.color[0]); /* R */ + VEC4_MUL(dest[0], dest[0], comp); /* R */ + VEC4_SCALAR(comp, llvmpipe->blend_color.color[1]); /* G */ + VEC4_MUL(dest[1], dest[1], comp); /* G */ + VEC4_SCALAR(comp, llvmpipe->blend_color.color[2]); /* B */ + VEC4_MUL(dest[2], dest[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, llvmpipe->blend_color.color[3]); /* A */ + VEC4_MUL(dest[0], dest[0], comp); /* R */ + VEC4_MUL(dest[1], dest[1], comp); /* G */ + VEC4_MUL(dest[2], dest[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + case PIPE_BLENDFACTOR_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, quadColor[0]); /* R */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_SUB(inv_comp, one, quadColor[1]); /* G */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_SUB(inv_comp, one, quadColor[2]); /* B */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quadColor[3]); + VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ + VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ + VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */ + VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */ + VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(dest[0], dest[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(dest[1], dest[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(dest[2], dest[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + float inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[0]); + VEC4_MUL(dest[0], dest[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[1]); + VEC4_MUL(dest[1], dest[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[2]); + VEC4_MUL(dest[2], dest[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[3]); + VEC4_MUL(dest[0], dest[0], inv_comp); + VEC4_MUL(dest[1], dest[1], inv_comp); + VEC4_MUL(dest[2], dest[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + /* XXX what are these? */ + assert(0); + break; + default: + assert(0); + } + + /* + * Compute dest/second term A + */ + switch (llvmpipe->blend->alpha_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_SRC_ALPHA: + VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */ + break; + case PIPE_BLENDFACTOR_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_DST_ALPHA: + VEC4_MUL(dest[3], dest[3], dest[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* illegal */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + float comp[4]; + VEC4_SCALAR(comp, llvmpipe->blend_color.color[3]); /* A */ + VEC4_MUL(dest[3], dest[3], comp); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[3], zero); /* A */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + float one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quadColor[3]); + VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + float inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[3]); /* A */ + VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + /* fall-through */ + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + float inv_comp[4]; + VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[3]); + VEC4_MUL(dest[3], dest[3], inv_comp); + } + break; + default: + assert(0); + } + + /* + * Combine RGB terms + */ + switch (llvmpipe->blend->rgb_func) { + case PIPE_BLEND_ADD: + VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */ + VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */ + VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */ + VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */ + VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */ + VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */ + VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */ + break; + default: + assert(0); + } + + /* + * Combine A terms + */ + switch (llvmpipe->blend->alpha_func) { + case PIPE_BLEND_ADD: + VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */ + break; + default: + assert(0); + } + + } /* cbuf loop */ + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quad); +} + + +static void blend_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void blend_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *lp_quad_blend_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = blend_begin; + stage->run = blend_quad; + stage->destroy = blend_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_bufloop.c b/src/gallium/drivers/llvmpipe/lp_quad_bufloop.c new file mode 100644 index 0000000000..2522c3c423 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_bufloop.c @@ -0,0 +1,74 @@ + +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_surface.h" +#include "lp_quad_pipe.h" + + +/** + * Loop over colorbuffers, passing quad to next stage each time. + */ +static void +cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + float tmp[PIPE_MAX_COLOR_BUFS][4][QUAD_SIZE]; + unsigned i; + + assert(sizeof(quad->outputs.color) == sizeof(tmp)); + assert(llvmpipe->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS); + + /* make copy of original colors since they can get modified + * by blending and masking. + * XXX we won't have to do this if the fragment program actually emits + * N separate colors and we're drawing to N color buffers (MRT). + * But if we emitted one color and glDrawBuffer(GL_FRONT_AND_BACK) is + * in effect, we need to save/restore colors like this. + */ + memcpy(tmp, quad->outputs.color, sizeof(tmp)); + + for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { + /* set current cbuffer */ +#if 0 /* obsolete & going away */ + llvmpipe->current_cbuf = i; +#endif + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quad); + + /* restore quad's colors for next buffer */ + memcpy(quad->outputs.color, tmp, sizeof(tmp)); + } +} + + +static void cbuf_loop_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void cbuf_loop_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +/** + * Create the colorbuffer loop stage. + * This is used to implement multiple render targets and GL_FRONT_AND_BACK + * rendering. + */ +struct quad_stage *lp_quad_bufloop_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = cbuf_loop_begin; + stage->run = cbuf_loop_quad; + stage->destroy = cbuf_loop_destroy; + + return stage; +} + diff --git a/src/gallium/drivers/llvmpipe/lp_quad_colormask.c b/src/gallium/drivers/llvmpipe/lp_quad_colormask.c new file mode 100644 index 0000000000..ef95eae454 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_colormask.c @@ -0,0 +1,116 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief quad colormask stage + * \author Brian Paul + */ + +#include "pipe/p_defines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_surface.h" +#include "lp_quad_pipe.h" +#include "lp_tile_cache.h" + + + +/** + * XXX colormask could be rolled into blending... + */ +static void +colormask_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) { + float dest[4][QUAD_SIZE]; + struct llvmpipe_cached_tile *tile + = lp_get_cached_tile(llvmpipe, + llvmpipe->cbuf_cache[cbuf], + quad->input.x0, quad->input.y0); + float (*quadColor)[4] = quad->output.color[cbuf]; + uint i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1); + int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1); + for (i = 0; i < 4; i++) { + dest[i][j] = tile->data.color[y][x][i]; + } + } + + /* R */ + if (!(llvmpipe->blend->colormask & PIPE_MASK_R)) + COPY_4V(quadColor[0], dest[0]); + + /* G */ + if (!(llvmpipe->blend->colormask & PIPE_MASK_G)) + COPY_4V(quadColor[1], dest[1]); + + /* B */ + if (!(llvmpipe->blend->colormask & PIPE_MASK_B)) + COPY_4V(quadColor[2], dest[2]); + + /* A */ + if (!(llvmpipe->blend->colormask & PIPE_MASK_A)) + COPY_4V(quadColor[3], dest[3]); + } + + /* pass quad to next stage */ + qs->next->run(qs->next, quad); +} + + +static void colormask_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void colormask_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *lp_quad_colormask_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = colormask_begin; + stage->run = colormask_quad; + stage->destroy = colormask_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_coverage.c b/src/gallium/drivers/llvmpipe/lp_quad_coverage.c new file mode 100644 index 0000000000..01c5982e85 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_coverage.c @@ -0,0 +1,94 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * \brief Apply AA coverage to quad alpha valus + * \author Brian Paul + */ + + +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_quad_pipe.h" + + +/** + * Multiply quad's alpha values by the fragment coverage. + */ +static void +coverage_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + const uint prim = quad->input.prim; + + if ((llvmpipe->rasterizer->poly_smooth && prim == QUAD_PRIM_TRI) || + (llvmpipe->rasterizer->line_smooth && prim == QUAD_PRIM_LINE) || + (llvmpipe->rasterizer->point_smooth && prim == QUAD_PRIM_POINT)) { + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) { + float (*quadColor)[4] = quad->output.color[cbuf]; + unsigned j; + for (j = 0; j < QUAD_SIZE; j++) { + assert(quad->input.coverage[j] >= 0.0); + assert(quad->input.coverage[j] <= 1.0); + quadColor[3][j] *= quad->input.coverage[j]; + } + } + } + + qs->next->run(qs->next, quad); +} + + +static void coverage_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void coverage_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *lp_quad_coverage_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = coverage_begin; + stage->run = coverage_quad; + stage->destroy = coverage_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_depth_test.c b/src/gallium/drivers/llvmpipe/lp_quad_depth_test.c new file mode 100644 index 0000000000..5a1daf0fed --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_depth_test.c @@ -0,0 +1,290 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Quad depth testing + */ + +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_surface.h" +#include "lp_quad_pipe.h" +#include "lp_tile_cache.h" + + +/** + * Do depth testing for a quad. + * Not static since it's used by the stencil code. + */ + +/* + * To increase efficiency, we should probably have multiple versions + * of this function that are specifically for Z16, Z32 and FP Z buffers. + * Try to effectively do that with codegen... + */ + +void +lp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + struct pipe_surface *ps = llvmpipe->framebuffer.zsbuf; + const enum pipe_format format = ps->format; + unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */ + unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */ + unsigned zmask = 0; + unsigned j; + struct llvmpipe_cached_tile *tile + = lp_get_cached_tile(llvmpipe, llvmpipe->zsbuf_cache, quad->input.x0, quad->input.y0); + + assert(ps); /* shouldn't get here if there's no zbuffer */ + + /* + * Convert quad's float depth values to int depth values (qzzzz). + * If the Z buffer stores integer values, we _have_ to do the depth + * compares with integers (not floats). Otherwise, the float->int->float + * conversion of Z values (which isn't an identity function) will cause + * Z-fighting errors. + * + * Also, get the zbuffer values (bzzzz) from the cached tile. + */ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + { + float scale = 65535.0; + + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); + } + + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + bzzzz[j] = tile->data.depth16[y][x]; + } + } + break; + case PIPE_FORMAT_Z32_UNORM: + { + double scale = (double) (uint) ~0UL; + + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); + } + + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + bzzzz[j] = tile->data.depth32[y][x]; + } + } + break; + case PIPE_FORMAT_X8Z24_UNORM: + /* fall-through */ + case PIPE_FORMAT_S8Z24_UNORM: + { + float scale = (float) ((1 << 24) - 1); + + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); + } + + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + bzzzz[j] = tile->data.depth32[y][x] & 0xffffff; + } + } + break; + case PIPE_FORMAT_Z24X8_UNORM: + /* fall-through */ + case PIPE_FORMAT_Z24S8_UNORM: + { + float scale = (float) ((1 << 24) - 1); + + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (unsigned) (quad->output.depth[j] * scale); + } + + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + bzzzz[j] = tile->data.depth32[y][x] >> 8; + } + } + break; + default: + assert(0); + } + + switch (llvmpipe->depth_stencil->depth.func) { + case PIPE_FUNC_NEVER: + /* zmask = 0 */ + break; + case PIPE_FUNC_LESS: + /* Note this is pretty much a single sse or cell instruction. + * Like this: quad->mask &= (quad->outputs.depth < zzzz); + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] < bzzzz[j]) + zmask |= 1 << j; + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] == bzzzz[j]) + zmask |= 1 << j; + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] <= bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] > bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] != bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] >= bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_ALWAYS: + zmask = MASK_ALL; + break; + default: + assert(0); + } + + quad->inout.mask &= zmask; + + if (llvmpipe->depth_stencil->depth.writemask) { + + /* This is also efficient with sse / spe instructions: + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + bzzzz[j] = qzzzz[j]; + } + } + + /* put updated Z values back into cached tile */ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.depth16[y][x] = (ushort) bzzzz[j]; + } + break; + case PIPE_FORMAT_X8Z24_UNORM: + /* fall-through */ + /* (yes, this falls through to a different case than above) */ + case PIPE_FORMAT_Z32_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = bzzzz[j]; + } + break; + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + uint s8z24 = tile->data.depth32[y][x]; + s8z24 = (s8z24 & 0xff000000) | bzzzz[j]; + tile->data.depth32[y][x] = s8z24; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + uint z24s8 = tile->data.depth32[y][x]; + z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 8); + tile->data.depth32[y][x] = z24s8; + } + break; + case PIPE_FORMAT_Z24X8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.depth32[y][x] = bzzzz[j] << 8; + } + break; + default: + assert(0); + } + } +} + + +static void +depth_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + lp_depth_test_quad(qs, quad); + + if (quad->inout.mask) + qs->next->run(qs->next, quad); +} + + +static void depth_test_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void depth_test_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *lp_quad_depth_test_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = depth_test_begin; + stage->run = depth_test_quad; + stage->destroy = depth_test_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_earlyz.c b/src/gallium/drivers/llvmpipe/lp_quad_earlyz.c new file mode 100644 index 0000000000..e4b4c3b55c --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_earlyz.c @@ -0,0 +1,88 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Quad early-z testing + */ + +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "lp_quad.h" +#include "lp_quad_pipe.h" + + +/** + * All this stage does is compute the quad's Z values (which is normally + * done by the shading stage). + * The next stage will do the actual depth test. + */ +static void +earlyz_quad( + struct quad_stage *qs, + struct quad_header *quad ) +{ + const float fx = (float) quad->input.x0; + const float fy = (float) quad->input.y0; + const float dzdx = quad->posCoef->dadx[2]; + const float dzdy = quad->posCoef->dady[2]; + const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; + + quad->output.depth[0] = z0; + quad->output.depth[1] = z0 + dzdx; + quad->output.depth[2] = z0 + dzdy; + quad->output.depth[3] = z0 + dzdx + dzdy; + + qs->next->run( qs->next, quad ); +} + +static void +earlyz_begin( + struct quad_stage *qs ) +{ + qs->next->begin( qs->next ); +} + +static void +earlyz_destroy( + struct quad_stage *qs ) +{ + FREE( qs ); +} + +struct quad_stage * +lp_quad_earlyz_stage( + struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT( quad_stage ); + + stage->llvmpipe = llvmpipe; + stage->begin = earlyz_begin; + stage->run = earlyz_quad; + stage->destroy = earlyz_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_fs.c b/src/gallium/drivers/llvmpipe/lp_quad_fs.c new file mode 100644 index 0000000000..cabc54155c --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_fs.c @@ -0,0 +1,192 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * Copyright 2008 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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. + * + **************************************************************************/ + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "util/u_math.h" +#include "util/u_memory.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_quad.h" +#include "lp_quad_pipe.h" +#include "lp_texture.h" +#include "lp_tex_sample.h" + + +struct quad_shade_stage +{ + struct quad_stage stage; /**< base class */ + struct tgsi_exec_machine *machine; + struct tgsi_exec_vector *inputs, *outputs; +}; + + +/** cast wrapper */ +static INLINE struct quad_shade_stage * +quad_shade_stage(struct quad_stage *qs) +{ + return (struct quad_shade_stage *) qs; +} + + +/** + * Execute fragment shader for the four fragments in the quad. + */ +static void +shade_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct quad_shade_stage *qss = quad_shade_stage( qs ); + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + struct tgsi_exec_machine *machine = qss->machine; + boolean z_written; + + /* Consts do not require 16 byte alignment. */ + machine->Consts = llvmpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; + + machine->InterpCoefs = quad->coef; + + /* run shader */ + quad->inout.mask &= llvmpipe->fs->run( llvmpipe->fs, machine, quad ); + + /* store outputs */ + z_written = FALSE; + { + const ubyte *sem_name = llvmpipe->fs->info.output_semantic_name; + const ubyte *sem_index = llvmpipe->fs->info.output_semantic_index; + const uint n = qss->stage.llvmpipe->fs->info.num_outputs; + uint i; + for (i = 0; i < n; i++) { + switch (sem_name[i]) { + case TGSI_SEMANTIC_COLOR: + { + uint cbuf = sem_index[i]; + memcpy(quad->output.color[cbuf], + &machine->Outputs[i].xyzw[0].f[0], + sizeof(quad->output.color[0]) ); + } + break; + case TGSI_SEMANTIC_POSITION: + { + uint j; + for (j = 0; j < 4; j++) { + quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j]; + } + z_written = TRUE; + } + break; + } + } + } + + if (!z_written) { + /* compute Z values now, as in the quad earlyz stage */ + /* XXX we should really only do this if the earlyz stage is not used */ + const float fx = (float) quad->input.x0; + const float fy = (float) quad->input.y0; + const float dzdx = quad->posCoef->dadx[2]; + const float dzdy = quad->posCoef->dady[2]; + const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy; + + quad->output.depth[0] = z0; + quad->output.depth[1] = z0 + dzdx; + quad->output.depth[2] = z0 + dzdy; + quad->output.depth[3] = z0 + dzdx + dzdy; + } + + /* shader may cull fragments */ + if (quad->inout.mask) { + qs->next->run( qs->next, quad ); + } +} + + +/** + * Per-primitive (or per-begin?) setup + */ +static void +shade_begin(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = quad_shade_stage(qs); + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + + llvmpipe->fs->prepare( llvmpipe->fs, + qss->machine, + (struct tgsi_sampler **) + llvmpipe->tgsi.frag_samplers_list ); + + qs->next->begin(qs->next); +} + + +static void +shade_destroy(struct quad_stage *qs) +{ + struct quad_shade_stage *qss = (struct quad_shade_stage *) qs; + + tgsi_exec_machine_destroy(qss->machine); + + FREE( qs ); +} + + +struct quad_stage * +lp_quad_shade_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage); + if (!qss) + goto fail; + + qss->stage.llvmpipe = llvmpipe; + qss->stage.begin = shade_begin; + qss->stage.run = shade_quad; + qss->stage.destroy = shade_destroy; + + qss->machine = tgsi_exec_machine_create(); + if (!qss->machine) + goto fail; + + return &qss->stage; + +fail: + if (qss && qss->machine) + tgsi_exec_machine_destroy(qss->machine); + + FREE(qss); + return NULL; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_occlusion.c b/src/gallium/drivers/llvmpipe/lp_quad_occlusion.c new file mode 100644 index 0000000000..6441ca30f2 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_occlusion.c @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * \brief Quad occlusion counter stage + * \author Brian Paul + */ + + +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_surface.h" +#include "lp_quad_pipe.h" + +static unsigned count_bits( unsigned val ) +{ + unsigned i; + + for (i = 0; val ; val >>= 1) + i += (val & 1); + + return i; +} + +static void +occlusion_count_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + + llvmpipe->occlusion_count += count_bits(quad->inout.mask); + + qs->next->run(qs->next, quad); +} + + +static void occlusion_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void occlusion_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *lp_quad_occlusion_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = occlusion_begin; + stage->run = occlusion_count_quad; + stage->destroy = occlusion_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_output.c b/src/gallium/drivers/llvmpipe/lp_quad_output.c new file mode 100644 index 0000000000..94d5f5a4c8 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_output.c @@ -0,0 +1,103 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_surface.h" +#include "lp_quad_pipe.h" +#include "lp_tile_cache.h" + + +/** + * Last step of quad processing: write quad colors to the framebuffer, + * taking mask into account. + */ +static void +output_quad(struct quad_stage *qs, struct quad_header *quad) +{ + /* in-tile pos: */ + const int itx = quad->input.x0 % TILE_SIZE; + const int ity = quad->input.y0 % TILE_SIZE; + + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + uint cbuf; + + /* loop over colorbuffer outputs */ + for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) { + struct llvmpipe_cached_tile *tile + = lp_get_cached_tile(llvmpipe, + llvmpipe->cbuf_cache[cbuf], + quad->input.x0, quad->input.y0); + float (*quadColor)[4] = quad->output.color[cbuf]; + int i, j; + + /* get/swizzle dest colors */ + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->inout.mask & (1 << j)) { + int x = itx + (j & 1); + int y = ity + (j >> 1); + for (i = 0; i < 4; i++) { /* loop over color chans */ + tile->data.color[y][x][i] = quadColor[i][j]; + } + if (0) { + debug_printf("lp write pixel %d,%d: %g, %g, %g\n", + quad->input.x0 + x, + quad->input.y0 + y, + quadColor[0][j], + quadColor[1][j], + quadColor[2][j]); + } + } + } + } +} + + +static void output_begin(struct quad_stage *qs) +{ + assert(qs->next == NULL); +} + + +static void output_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *lp_quad_output_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = output_begin; + stage->run = output_quad; + stage->destroy = output_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_pipe.c b/src/gallium/drivers/llvmpipe/lp_quad_pipe.c new file mode 100644 index 0000000000..378acf8f86 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_pipe.c @@ -0,0 +1,118 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "lp_context.h" +#include "lp_state.h" +#include "pipe/p_shader_tokens.h" + +static void +lp_push_quad_first( + struct llvmpipe_context *lp, + struct quad_stage *quad, + uint i ) +{ + quad->next = lp->quad[i].first; + lp->quad[i].first = quad; +} + +static void +lp_build_depth_stencil( + struct llvmpipe_context *lp, + uint i ) +{ + if (lp->depth_stencil->stencil[0].enabled || + lp->depth_stencil->stencil[1].enabled) { + lp_push_quad_first( lp, lp->quad[i].stencil_test, i ); + } + else if (lp->depth_stencil->depth.enabled && + lp->framebuffer.zsbuf) { + lp_push_quad_first( lp, lp->quad[i].depth_test, i ); + } +} + +void +lp_build_quad_pipeline(struct llvmpipe_context *lp) +{ + uint i; + + boolean early_depth_test = + lp->depth_stencil->depth.enabled && + lp->framebuffer.zsbuf && + !lp->depth_stencil->alpha.enabled && + !lp->fs->info.uses_kill && + !lp->fs->info.writes_z; + + /* build up the pipeline in reverse order... */ + for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { + lp->quad[i].first = lp->quad[i].output; + + if (lp->blend->colormask != 0xf) { + lp_push_quad_first( lp, lp->quad[i].colormask, i ); + } + + if (lp->blend->blend_enable || + lp->blend->logicop_enable) { + lp_push_quad_first( lp, lp->quad[i].blend, i ); + } + + if (lp->active_query_count) { + lp_push_quad_first( lp, lp->quad[i].occlusion, i ); + } + + if (lp->rasterizer->poly_smooth || + lp->rasterizer->line_smooth || + lp->rasterizer->point_smooth) { + lp_push_quad_first( lp, lp->quad[i].coverage, i ); + } + + if (!early_depth_test) { + lp_build_depth_stencil( lp, i ); + } + + if (lp->depth_stencil->alpha.enabled) { + lp_push_quad_first( lp, lp->quad[i].alpha_test, i ); + } + + /* XXX always enable shader? */ + if (1) { + lp_push_quad_first( lp, lp->quad[i].shade, i ); + } + + if (early_depth_test) { + lp_build_depth_stencil( lp, i ); + lp_push_quad_first( lp, lp->quad[i].earlyz, i ); + } + +#if !USE_DRAW_STAGE_PSTIPPLE + if (lp->rasterizer->poly_stipple_enable) { + lp_push_quad_first( lp, lp->quad[i].polygon_stipple, i ); + } +#endif + } +} + diff --git a/src/gallium/drivers/llvmpipe/lp_quad_pipe.h b/src/gallium/drivers/llvmpipe/lp_quad_pipe.h new file mode 100644 index 0000000000..5995fdb6c6 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_pipe.h @@ -0,0 +1,74 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_QUAD_PIPE_H +#define SP_QUAD_PIPE_H + + +struct llvmpipe_context; +struct quad_header; + + +/** + * Fragment processing is performed on 2x2 blocks of pixels called "quads". + * Quad processing is performed with a pipeline of stages represented by + * this type. + */ +struct quad_stage { + struct llvmpipe_context *llvmpipe; + + struct quad_stage *next; + + void (*begin)(struct quad_stage *qs); + + /** the stage action */ + void (*run)(struct quad_stage *qs, struct quad_header *quad); + + void (*destroy)(struct quad_stage *qs); +}; + + +struct quad_stage *lp_quad_polygon_stipple_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_earlyz_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_shade_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_alpha_test_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_stencil_test_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_depth_test_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_occlusion_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_coverage_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_blend_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_colormask_stage( struct llvmpipe_context *llvmpipe ); +struct quad_stage *lp_quad_output_stage( struct llvmpipe_context *llvmpipe ); + +void lp_build_quad_pipeline(struct llvmpipe_context *lp); + +void lp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad); + +#endif /* SP_QUAD_PIPE_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_quad_stencil.c b/src/gallium/drivers/llvmpipe/lp_quad_stencil.c new file mode 100644 index 0000000000..4c99067d45 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_stencil.c @@ -0,0 +1,352 @@ + +/** + * \brief Quad stencil testing + */ + + +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_surface.h" +#include "lp_tile_cache.h" +#include "lp_quad_pipe.h" +#include "pipe/p_defines.h" +#include "util/u_memory.h" + + +/** Only 8-bit stencil supported */ +#define STENCIL_MAX 0xff + + +/** + * Do the basic stencil test (compare stencil buffer values against the + * reference value. + * + * \param stencilVals the stencil values from the stencil buffer + * \param func the stencil func (PIPE_FUNC_x) + * \param ref the stencil reference value + * \param valMask the stencil value mask indicating which bits of the stencil + * values and ref value are to be used. + * \return mask indicating which pixels passed the stencil test + */ +static unsigned +do_stencil_test(const ubyte stencilVals[QUAD_SIZE], unsigned func, + unsigned ref, unsigned valMask) +{ + unsigned passMask = 0x0; + unsigned j; + + ref &= valMask; + + switch (func) { + case PIPE_FUNC_NEVER: + /* passMask = 0x0 */ + break; + case PIPE_FUNC_LESS: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref < (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref == (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref <= (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref > (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref != (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (ref >= (stencilVals[j] & valMask)) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_ALWAYS: + passMask = MASK_ALL; + break; + default: + assert(0); + } + + return passMask; +} + + +/** + * Apply the stencil operator to stencil values. + * + * \param stencilVals the stencil buffer values (read and written) + * \param mask indicates which pixels to update + * \param op the stencil operator (PIPE_STENCIL_OP_x) + * \param ref the stencil reference value + * \param wrtMask writemask controlling which bits are changed in the + * stencil values + */ +static void +apply_stencil_op(ubyte stencilVals[QUAD_SIZE], + unsigned mask, unsigned op, ubyte ref, ubyte wrtMask) +{ + unsigned j; + ubyte newstencil[QUAD_SIZE]; + + for (j = 0; j < QUAD_SIZE; j++) { + newstencil[j] = stencilVals[j]; + } + + switch (op) { + case PIPE_STENCIL_OP_KEEP: + /* no-op */ + break; + case PIPE_STENCIL_OP_ZERO: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = 0; + } + } + break; + case PIPE_STENCIL_OP_REPLACE: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = ref; + } + } + break; + case PIPE_STENCIL_OP_INCR: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + if (stencilVals[j] < STENCIL_MAX) { + newstencil[j] = stencilVals[j] + 1; + } + } + } + break; + case PIPE_STENCIL_OP_DECR: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + if (stencilVals[j] > 0) { + newstencil[j] = stencilVals[j] - 1; + } + } + } + break; + case PIPE_STENCIL_OP_INCR_WRAP: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = stencilVals[j] + 1; + } + } + break; + case PIPE_STENCIL_OP_DECR_WRAP: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = stencilVals[j] - 1; + } + } + break; + case PIPE_STENCIL_OP_INVERT: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = ~stencilVals[j]; + } + } + break; + default: + assert(0); + } + + /* + * update the stencil values + */ + if (wrtMask != STENCIL_MAX) { + /* apply bit-wise stencil buffer writemask */ + for (j = 0; j < QUAD_SIZE; j++) { + stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & stencilVals[j]); + } + } + else { + for (j = 0; j < QUAD_SIZE; j++) { + stencilVals[j] = newstencil[j]; + } + } +} + + +/** + * Do stencil (and depth) testing. Stenciling depends on the outcome of + * depth testing. + */ +static void +stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + struct pipe_surface *ps = llvmpipe->framebuffer.zsbuf; + unsigned func, zFailOp, zPassOp, failOp; + ubyte ref, wrtMask, valMask; + ubyte stencilVals[QUAD_SIZE]; + struct llvmpipe_cached_tile *tile + = lp_get_cached_tile(llvmpipe, llvmpipe->zsbuf_cache, quad->input.x0, quad->input.y0); + uint j; + uint face = quad->input.facing; + + if (!llvmpipe->depth_stencil->stencil[1].enabled) { + /* single-sided stencil test, use front (face=0) state */ + face = 0; + } + + /* choose front or back face function, operator, etc */ + /* XXX we could do these initializations once per primitive */ + func = llvmpipe->depth_stencil->stencil[face].func; + failOp = llvmpipe->depth_stencil->stencil[face].fail_op; + zFailOp = llvmpipe->depth_stencil->stencil[face].zfail_op; + zPassOp = llvmpipe->depth_stencil->stencil[face].zpass_op; + ref = llvmpipe->depth_stencil->stencil[face].ref_value; + wrtMask = llvmpipe->depth_stencil->stencil[face].writemask; + valMask = llvmpipe->depth_stencil->stencil[face].valuemask; + + assert(ps); /* shouldn't get here if there's no stencil buffer */ + + /* get stencil values from cached tile */ + switch (ps->format) { + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.depth32[y][x] >> 24; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.depth32[y][x] & 0xff; + } + break; + case PIPE_FORMAT_S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + stencilVals[j] = tile->data.stencil8[y][x]; + } + break; + default: + assert(0); + } + + /* do the stencil test first */ + { + unsigned passMask, failMask; + passMask = do_stencil_test(stencilVals, func, ref, valMask); + failMask = quad->inout.mask & ~passMask; + quad->inout.mask &= passMask; + + if (failOp != PIPE_STENCIL_OP_KEEP) { + apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask); + } + } + + if (quad->inout.mask) { + /* now the pixels that passed the stencil test are depth tested */ + if (llvmpipe->depth_stencil->depth.enabled) { + const unsigned origMask = quad->inout.mask; + + lp_depth_test_quad(qs, quad); /* quad->mask is updated */ + + /* update stencil buffer values according to z pass/fail result */ + if (zFailOp != PIPE_STENCIL_OP_KEEP) { + const unsigned failMask = origMask & ~quad->inout.mask; + apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask); + } + + if (zPassOp != PIPE_STENCIL_OP_KEEP) { + const unsigned passMask = origMask & quad->inout.mask; + apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask); + } + } + else { + /* no depth test, apply Zpass operator to stencil buffer values */ + apply_stencil_op(stencilVals, quad->inout.mask, zPassOp, ref, wrtMask); + } + + } + + /* put new stencil values into cached tile */ + switch (ps->format) { + case PIPE_FORMAT_S8Z24_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + uint s8z24 = tile->data.depth32[y][x]; + s8z24 = (stencilVals[j] << 24) | (s8z24 & 0xffffff); + tile->data.depth32[y][x] = s8z24; + } + break; + case PIPE_FORMAT_Z24S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + uint z24s8 = tile->data.depth32[y][x]; + z24s8 = (z24s8 & 0xffffff00) | stencilVals[j]; + tile->data.depth32[y][x] = z24s8; + } + break; + case PIPE_FORMAT_S8_UNORM: + for (j = 0; j < QUAD_SIZE; j++) { + int x = quad->input.x0 % TILE_SIZE + (j & 1); + int y = quad->input.y0 % TILE_SIZE + (j >> 1); + tile->data.stencil8[y][x] = stencilVals[j]; + } + break; + default: + assert(0); + } + + if (quad->inout.mask) + qs->next->run(qs->next, quad); +} + + +static void stencil_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void stencil_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage *lp_quad_stencil_test_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = stencil_begin; + stage->run = stencil_test_quad; + stage->destroy = stencil_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_quad_stipple.c b/src/gallium/drivers/llvmpipe/lp_quad_stipple.c new file mode 100644 index 0000000000..616394619a --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_quad_stipple.c @@ -0,0 +1,77 @@ + +/** + * quad polygon stipple stage + */ + +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_quad_pipe.h" +#include "pipe/p_defines.h" +#include "util/u_memory.h" + + +/** + * Apply polygon stipple to quads produced by triangle rasterization + */ +static void +stipple_quad(struct quad_stage *qs, struct quad_header *quad) +{ + static const uint bit31 = 1 << 31; + static const uint bit30 = 1 << 30; + + if (quad->input.prim == QUAD_PRIM_TRI) { + struct llvmpipe_context *llvmpipe = qs->llvmpipe; + /* need to invert Y to index into OpenGL's stipple pattern */ + const int col0 = quad->input.x0 % 32; + const int y0 = quad->input.y0; + const int y1 = y0 + 1; + const uint stipple0 = llvmpipe->poly_stipple.stipple[y0 % 32]; + const uint stipple1 = llvmpipe->poly_stipple.stipple[y1 % 32]; + + /* turn off quad mask bits that fail the stipple test */ + if ((stipple0 & (bit31 >> col0)) == 0) + quad->inout.mask &= ~MASK_TOP_LEFT; + + if ((stipple0 & (bit30 >> col0)) == 0) + quad->inout.mask &= ~MASK_TOP_RIGHT; + + if ((stipple1 & (bit31 >> col0)) == 0) + quad->inout.mask &= ~MASK_BOTTOM_LEFT; + + if ((stipple1 & (bit30 >> col0)) == 0) + quad->inout.mask &= ~MASK_BOTTOM_RIGHT; + + if (!quad->inout.mask) { + /* all fragments failed stipple test, end of quad pipeline */ + return; + } + } + + qs->next->run(qs->next, quad); +} + + +static void stipple_begin(struct quad_stage *qs) +{ + qs->next->begin(qs->next); +} + + +static void stipple_destroy(struct quad_stage *qs) +{ + FREE( qs ); +} + + +struct quad_stage * +lp_quad_polygon_stipple_stage( struct llvmpipe_context *llvmpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->llvmpipe = llvmpipe; + stage->begin = stipple_begin; + stage->run = stipple_quad; + stage->destroy = stipple_destroy; + + return stage; +} diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c new file mode 100644 index 0000000000..7aa8e9d3fe --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_query.c @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_query.h" +#include "lp_state.h" + +struct llvmpipe_query { + uint64_t start; + uint64_t end; +}; + + +static struct llvmpipe_query *llvmpipe_query( struct pipe_query *p ) +{ + return (struct llvmpipe_query *)p; +} + +static struct pipe_query * +llvmpipe_create_query(struct pipe_context *pipe, + unsigned type) +{ + assert(type == PIPE_QUERY_OCCLUSION_COUNTER); + return (struct pipe_query *)CALLOC_STRUCT( llvmpipe_query ); +} + + +static void +llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q) +{ + FREE(q); +} + + +static void +llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + struct llvmpipe_query *sq = llvmpipe_query(q); + + sq->start = llvmpipe->occlusion_count; + llvmpipe->active_query_count++; + llvmpipe->dirty |= SP_NEW_QUERY; +} + + +static void +llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + struct llvmpipe_query *sq = llvmpipe_query(q); + + llvmpipe->active_query_count--; + sq->end = llvmpipe->occlusion_count; + llvmpipe->dirty |= SP_NEW_QUERY; +} + + +static boolean +llvmpipe_get_query_result(struct pipe_context *pipe, + struct pipe_query *q, + boolean wait, + uint64_t *result ) +{ + struct llvmpipe_query *sq = llvmpipe_query(q); + *result = sq->end - sq->start; + return TRUE; +} + + +void llvmpipe_init_query_funcs(struct llvmpipe_context *llvmpipe ) +{ + llvmpipe->pipe.create_query = llvmpipe_create_query; + llvmpipe->pipe.destroy_query = llvmpipe_destroy_query; + llvmpipe->pipe.begin_query = llvmpipe_begin_query; + llvmpipe->pipe.end_query = llvmpipe_end_query; + llvmpipe->pipe.get_query_result = llvmpipe_get_query_result; +} + + diff --git a/src/gallium/drivers/llvmpipe/lp_query.h b/src/gallium/drivers/llvmpipe/lp_query.h new file mode 100644 index 0000000000..58eba089d8 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_query.h @@ -0,0 +1,39 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell + */ + +#ifndef SP_QUERY_H +#define SP_QUERY_H + +struct llvmpipe_context; +extern void llvmpipe_init_query_funcs(struct llvmpipe_context * ); + + +#endif /* SP_QUERY_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c new file mode 100644 index 0000000000..b71f15678e --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -0,0 +1,190 @@ +/************************************************************************** + * + * 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 "util/u_simple_screen.h" +#include "pipe/internal/p_winsys_screen.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" + +#include "lp_texture.h" +#include "lp_winsys.h" +#include "lp_screen.h" + + +static const char * +llvmpipe_get_vendor(struct pipe_screen *screen) +{ + return "Tungsten Graphics, Inc."; +} + + +static const char * +llvmpipe_get_name(struct pipe_screen *screen) +{ + return "llvmpipe"; +} + + +static int +llvmpipe_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return PIPE_MAX_SAMPLERS; + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + return PIPE_MAX_SAMPLERS; + case PIPE_CAP_NPOT_TEXTURES: + return 1; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 1; + case PIPE_CAP_GLSL: + return 1; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 1; + case PIPE_CAP_MAX_RENDER_TARGETS: + return PIPE_MAX_COLOR_BUFS; + case PIPE_CAP_OCCLUSION_QUERY: + return 1; + case PIPE_CAP_TEXTURE_MIRROR_CLAMP: + return 1; + case PIPE_CAP_TEXTURE_MIRROR_REPEAT: + return 1; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 13; /* max 4Kx4K */ + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 8; /* max 128x128x128 */ + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 13; /* max 4Kx4K */ + case PIPE_CAP_TGSI_CONT_SUPPORTED: + return 1; + case PIPE_CAP_BLEND_EQUATION_SEPARATE: + return 1; + default: + return 0; + } +} + + +static float +llvmpipe_get_paramf(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 255.0; /* arbitrary */ + case PIPE_CAP_MAX_POINT_WIDTH: + /* fall-through */ + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 255.0; /* arbitrary */ + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 16.0; /* not actually signficant at this time */ + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 16.0; /* arbitrary */ + default: + return 0; + } +} + + +/** + * Query format support for creating a texture, drawing surface, etc. + * \param format the format to test + * \param type one of PIPE_TEXTURE, PIPE_SURFACE + */ +static boolean +llvmpipe_is_format_supported( struct pipe_screen *screen, + enum pipe_format format, + enum pipe_texture_target target, + unsigned tex_usage, + unsigned geom_flags ) +{ + assert(target == PIPE_TEXTURE_1D || + target == PIPE_TEXTURE_2D || + target == PIPE_TEXTURE_3D || + target == PIPE_TEXTURE_CUBE); + + switch(format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + return FALSE; + default: + return TRUE; + } +} + + +static void +llvmpipe_destroy_screen( struct pipe_screen *screen ) +{ + struct pipe_winsys *winsys = screen->winsys; + + if(winsys->destroy) + winsys->destroy(winsys); + + FREE(screen); +} + + + +/** + * Create a new pipe_screen object + * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen). + */ +struct pipe_screen * +llvmpipe_create_screen(struct pipe_winsys *winsys) +{ + struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen); + + if (!screen) + return NULL; + + screen->base.winsys = winsys; + + screen->base.destroy = llvmpipe_destroy_screen; + + screen->base.get_name = llvmpipe_get_name; + screen->base.get_vendor = llvmpipe_get_vendor; + screen->base.get_param = llvmpipe_get_param; + screen->base.get_paramf = llvmpipe_get_paramf; + screen->base.is_format_supported = llvmpipe_is_format_supported; + + llvmpipe_init_screen_texture_funcs(&screen->base); + u_simple_screen_init(&screen->base); + + return &screen->base; +} diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h new file mode 100644 index 0000000000..9f79510c4d --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_screen.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_SCREEN_H +#define SP_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + + + +struct llvmpipe_screen { + struct pipe_screen base; + + /* Increments whenever textures are modified. Contexts can track + * this. + */ + unsigned timestamp; +}; + + + + +static INLINE struct llvmpipe_screen * +llvmpipe_screen( struct pipe_screen *pipe ) +{ + return (struct llvmpipe_screen *)pipe; +} + + +#endif /* SP_SCREEN_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c new file mode 100644 index 0000000000..1bfe9d4852 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -0,0 +1,1550 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \brief Primitive rasterization/rendering (points, lines, triangles) + * + * \author Keith Whitwell + * \author Brian Paul + */ + +#include "lp_context.h" +#include "lp_prim_setup.h" +#include "lp_quad.h" +#include "lp_quad_pipe.h" +#include "lp_setup.h" +#include "lp_state.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_thread.h" +#include "util/u_math.h" +#include "util/u_memory.h" + + +#define DEBUG_VERTS 0 +#define DEBUG_FRAGS 0 + +/** + * Triangle edge info + */ +struct edge { + float dx; /**< X(v1) - X(v0), used only during setup */ + float dy; /**< Y(v1) - Y(v0), used only during setup */ + float dxdy; /**< dx/dy */ + float sx, sy; /**< first sample point coord */ + int lines; /**< number of lines on this edge */ +}; + +#if SP_NUM_QUAD_THREADS > 1 + +/* Set to 1 if you want other threads to be instantly + * notified of pending jobs. + */ +#define INSTANT_NOTEMPTY_NOTIFY 0 + +struct thread_info +{ + struct setup_context *setup; + uint id; + pipe_thread handle; +}; + +struct quad_job; + +typedef void (* quad_job_routine)( struct setup_context *setup, uint thread, struct quad_job *job ); + +struct quad_job +{ + struct quad_header_input input; + struct quad_header_inout inout; + quad_job_routine routine; +}; + +#define NUM_QUAD_JOBS 64 + +struct quad_job_que +{ + struct quad_job jobs[NUM_QUAD_JOBS]; + uint first; + uint last; + pipe_mutex que_mutex; + pipe_condvar que_notfull_condvar; + pipe_condvar que_notempty_condvar; + uint jobs_added; + uint jobs_done; + pipe_condvar que_done_condvar; +}; + +static void +add_quad_job( struct quad_job_que *que, struct quad_header *quad, quad_job_routine routine ) +{ +#if INSTANT_NOTEMPTY_NOTIFY + boolean empty; +#endif + + /* Wait for empty slot, see if the que is empty. + */ + pipe_mutex_lock( que->que_mutex ); + while ((que->last + 1) % NUM_QUAD_JOBS == que->first) { +#if !INSTANT_NOTEMPTY_NOTIFY + pipe_condvar_broadcast( que->que_notempty_condvar ); +#endif + pipe_condvar_wait( que->que_notfull_condvar, que->que_mutex ); + } +#if INSTANT_NOTEMPTY_NOTIFY + empty = que->last == que->first; +#endif + que->jobs_added++; + pipe_mutex_unlock( que->que_mutex ); + + /* Submit new job. + */ + que->jobs[que->last].input = quad->input; + que->jobs[que->last].inout = quad->inout; + que->jobs[que->last].routine = routine; + que->last = (que->last + 1) % NUM_QUAD_JOBS; + +#if INSTANT_NOTEMPTY_NOTIFY + /* If the que was empty, notify consumers there's a job to be done. + */ + if (empty) { + pipe_mutex_lock( que->que_mutex ); + pipe_condvar_broadcast( que->que_notempty_condvar ); + pipe_mutex_unlock( que->que_mutex ); + } +#endif +} + +#endif + +/** + * Triangle setup info (derived from draw_stage). + * Also used for line drawing (taking some liberties). + */ +struct setup_context { + struct llvmpipe_context *llvmpipe; + + /* Vertices are just an array of floats making up each attribute in + * turn. Currently fixed at 4 floats, but should change in time. + * Codegen will help cope with this. + */ + const float (*vmax)[4]; + const float (*vmid)[4]; + const float (*vmin)[4]; + const float (*vprovoke)[4]; + + struct edge ebot; + struct edge etop; + struct edge emaj; + + float oneoverarea; + + struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS]; + struct tgsi_interp_coef posCoef; /* For Z, W */ + struct quad_header quad; + +#if SP_NUM_QUAD_THREADS > 1 + struct quad_job_que que; + struct thread_info threads[SP_NUM_QUAD_THREADS]; +#endif + + struct { + int left[2]; /**< [0] = row0, [1] = row1 */ + int right[2]; + int y; + unsigned y_flags; + unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */ + } span; + +#if DEBUG_FRAGS + uint numFragsEmitted; /**< per primitive */ + uint numFragsWritten; /**< per primitive */ +#endif + + unsigned winding; /* which winding to cull */ +}; + +#if SP_NUM_QUAD_THREADS > 1 + +static PIPE_THREAD_ROUTINE( quad_thread, param ) +{ + struct thread_info *info = (struct thread_info *) param; + struct quad_job_que *que = &info->setup->que; + + for (;;) { + struct quad_job job; + boolean full; + + /* Wait for an available job. + */ + pipe_mutex_lock( que->que_mutex ); + while (que->last == que->first) + pipe_condvar_wait( que->que_notempty_condvar, que->que_mutex ); + + /* See if the que is full. + */ + full = (que->last + 1) % NUM_QUAD_JOBS == que->first; + + /* Take a job and remove it from que. + */ + job = que->jobs[que->first]; + que->first = (que->first + 1) % NUM_QUAD_JOBS; + + /* Notify the producer if the que is not full. + */ + if (full) + pipe_condvar_signal( que->que_notfull_condvar ); + pipe_mutex_unlock( que->que_mutex ); + + job.routine( info->setup, info->id, &job ); + + /* Notify the producer if that's the last finished job. + */ + pipe_mutex_lock( que->que_mutex ); + que->jobs_done++; + if (que->jobs_added == que->jobs_done) + pipe_condvar_signal( que->que_done_condvar ); + pipe_mutex_unlock( que->que_mutex ); + } + + return NULL; +} + +#define WAIT_FOR_COMPLETION(setup) \ + do {\ + pipe_mutex_lock( setup->que.que_mutex );\ + if (!INSTANT_NOTEMPTY_NOTIFY)\ + pipe_condvar_broadcast( setup->que.que_notempty_condvar );\ + while (setup->que.jobs_added != setup->que.jobs_done)\ + pipe_condvar_wait( setup->que.que_done_condvar, setup->que.que_mutex );\ + pipe_mutex_unlock( setup->que.que_mutex );\ + } while (0) + +#else + +#define WAIT_FOR_COMPLETION(setup) ((void) 0) + +#endif + + + +/** + * Do triangle cull test using tri determinant (sign indicates orientation) + * \return true if triangle is to be culled. + */ +static INLINE boolean +cull_tri(const struct setup_context *setup, float det) +{ + if (det != 0) { + /* if (det < 0 then Z points toward camera and triangle is + * counter-clockwise winding. + */ + unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; + + if ((winding & setup->winding) == 0) + return FALSE; + } + + /* Culled: + */ + return TRUE; +} + + + +/** + * Clip setup->quad against the scissor/surface bounds. + */ +static INLINE void +quad_clip( struct setup_context *setup, struct quad_header *quad ) +{ + const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; + const int minx = (int) cliprect->minx; + const int maxx = (int) cliprect->maxx; + const int miny = (int) cliprect->miny; + const int maxy = (int) cliprect->maxy; + + if (quad->input.x0 >= maxx || + quad->input.y0 >= maxy || + quad->input.x0 + 1 < minx || + quad->input.y0 + 1 < miny) { + /* totally clipped */ + quad->inout.mask = 0x0; + return; + } + if (quad->input.x0 < minx) + quad->inout.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); + if (quad->input.y0 < miny) + quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); + if (quad->input.x0 == maxx - 1) + quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); + if (quad->input.y0 == maxy - 1) + quad->inout.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); +} + + +/** + * Emit a quad (pass to next stage) with clipping. + */ +static INLINE void +clip_emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread ) +{ + quad_clip( setup, quad ); + if (quad->inout.mask) { + struct llvmpipe_context *lp = setup->llvmpipe; + + lp->quad[thread].first->run( lp->quad[thread].first, quad ); + } +} + +#if SP_NUM_QUAD_THREADS > 1 + +static void +clip_emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job ) +{ + struct quad_header quad; + + quad.input = job->input; + quad.inout = job->inout; + quad.coef = setup->quad.coef; + quad.posCoef = setup->quad.posCoef; + quad.nr_attrs = setup->quad.nr_attrs; + clip_emit_quad( setup, &quad, thread ); +} + +#define CLIP_EMIT_QUAD(setup) add_quad_job( &setup->que, &setup->quad, clip_emit_quad_job ) + +#else + +#define CLIP_EMIT_QUAD(setup) clip_emit_quad( setup, &setup->quad, 0 ) + +#endif + +/** + * Emit a quad (pass to next stage). No clipping is done. + */ +static INLINE void +emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread ) +{ + struct llvmpipe_context *lp = setup->llvmpipe; +#if DEBUG_FRAGS + uint mask = quad->inout.mask; +#endif + +#if DEBUG_FRAGS + if (mask & 1) setup->numFragsEmitted++; + if (mask & 2) setup->numFragsEmitted++; + if (mask & 4) setup->numFragsEmitted++; + if (mask & 8) setup->numFragsEmitted++; +#endif + lp->quad[thread].first->run( lp->quad[thread].first, quad ); +#if DEBUG_FRAGS + mask = quad->inout.mask; + if (mask & 1) setup->numFragsWritten++; + if (mask & 2) setup->numFragsWritten++; + if (mask & 4) setup->numFragsWritten++; + if (mask & 8) setup->numFragsWritten++; +#endif +} + +#if SP_NUM_QUAD_THREADS > 1 + +static void +emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job ) +{ + struct quad_header quad; + + quad.input = job->input; + quad.inout = job->inout; + quad.coef = setup->quad.coef; + quad.posCoef = setup->quad.posCoef; + quad.nr_attrs = setup->quad.nr_attrs; + emit_quad( setup, &quad, thread ); +} + +#define EMIT_QUAD(setup,x,y,mask) do {\ + setup->quad.input.x0 = x;\ + setup->quad.input.y0 = y;\ + setup->quad.inout.mask = mask;\ + add_quad_job( &setup->que, &setup->quad, emit_quad_job );\ + } while (0) + +#else + +#define EMIT_QUAD(setup,x,y,mask) do {\ + setup->quad.input.x0 = x;\ + setup->quad.input.y0 = y;\ + setup->quad.inout.mask = mask;\ + emit_quad( setup, &setup->quad, 0 );\ + } while (0) + +#endif + +/** + * Given an X or Y coordinate, return the block/quad coordinate that it + * belongs to. + */ +static INLINE int block( int x ) +{ + return x & ~1; +} + + +/** + * Render a horizontal span of quads + */ +static void flush_spans( struct setup_context *setup ) +{ + const int xleft0 = setup->span.left[0]; + const int xleft1 = setup->span.left[1]; + const int xright0 = setup->span.right[0]; + const int xright1 = setup->span.right[1]; + int minleft, maxright; + int x; + + switch (setup->span.y_flags) { + case 0x3: + /* both odd and even lines written (both quad rows) */ + minleft = block(MIN2(xleft0, xleft1)); + maxright = block(MAX2(xright0, xright1)); + for (x = minleft; x <= maxright; x += 2) { + /* determine which of the four pixels is inside the span bounds */ + uint mask = 0x0; + if (x >= xleft0 && x < xright0) + mask |= MASK_TOP_LEFT; + if (x >= xleft1 && x < xright1) + mask |= MASK_BOTTOM_LEFT; + if (x+1 >= xleft0 && x+1 < xright0) + mask |= MASK_TOP_RIGHT; + if (x+1 >= xleft1 && x+1 < xright1) + mask |= MASK_BOTTOM_RIGHT; + if (mask) + EMIT_QUAD( setup, x, setup->span.y, mask ); + } + break; + + case 0x1: + /* only even line written (quad top row) */ + minleft = block(xleft0); + maxright = block(xright0); + for (x = minleft; x <= maxright; x += 2) { + uint mask = 0x0; + if (x >= xleft0 && x < xright0) + mask |= MASK_TOP_LEFT; + if (x+1 >= xleft0 && x+1 < xright0) + mask |= MASK_TOP_RIGHT; + if (mask) + EMIT_QUAD( setup, x, setup->span.y, mask ); + } + break; + + case 0x2: + /* only odd line written (quad bottom row) */ + minleft = block(xleft1); + maxright = block(xright1); + for (x = minleft; x <= maxright; x += 2) { + uint mask = 0x0; + if (x >= xleft1 && x < xright1) + mask |= MASK_BOTTOM_LEFT; + if (x+1 >= xleft1 && x+1 < xright1) + mask |= MASK_BOTTOM_RIGHT; + if (mask) + EMIT_QUAD( setup, x, setup->span.y, mask ); + } + break; + + default: + return; + } + + setup->span.y = 0; + setup->span.y_flags = 0; + setup->span.right[0] = 0; + setup->span.right[1] = 0; +} + + +#if DEBUG_VERTS +static void print_vertex(const struct setup_context *setup, + const float (*v)[4]) +{ + int i; + debug_printf(" Vertex: (%p)\n", v); + for (i = 0; i < setup->quad.nr_attrs; i++) { + debug_printf(" %d: %f %f %f %f\n", i, + v[i][0], v[i][1], v[i][2], v[i][3]); + if (util_is_inf_or_nan(v[i][0])) { + debug_printf(" NaN!\n"); + } + } +} +#endif + +/** + * Sort the vertices from top to bottom order, setting up the triangle + * edge fields (ebot, emaj, etop). + * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise + */ +static boolean setup_sort_vertices( struct setup_context *setup, + float det, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + setup->vprovoke = v2; + + /* determine bottom to top order of vertices */ + { + float y0 = v0[0][1]; + float y1 = v1[0][1]; + float y2 = v2[0][1]; + if (y0 <= y1) { + if (y1 <= y2) { + /* y0<=y1<=y2 */ + setup->vmin = v0; + setup->vmid = v1; + setup->vmax = v2; + } + else if (y2 <= y0) { + /* y2<=y0<=y1 */ + setup->vmin = v2; + setup->vmid = v0; + setup->vmax = v1; + } + else { + /* y0<=y2<=y1 */ + setup->vmin = v0; + setup->vmid = v2; + setup->vmax = v1; + } + } + else { + if (y0 <= y2) { + /* y1<=y0<=y2 */ + setup->vmin = v1; + setup->vmid = v0; + setup->vmax = v2; + } + else if (y2 <= y1) { + /* y2<=y1<=y0 */ + setup->vmin = v2; + setup->vmid = v1; + setup->vmax = v0; + } + else { + /* y1<=y2<=y0 */ + setup->vmin = v1; + setup->vmid = v2; + setup->vmax = v0; + } + } + } + + setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0]; + setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1]; + setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; + setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; + setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0]; + setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1]; + + /* + * Compute triangle's area. Use 1/area to compute partial + * derivatives of attributes later. + * + * The area will be the same as prim->det, but the sign may be + * different depending on how the vertices get sorted above. + * + * To determine whether the primitive is front or back facing we + * use the prim->det value because its sign is correct. + */ + { + const float area = (setup->emaj.dx * setup->ebot.dy - + setup->ebot.dx * setup->emaj.dy); + + setup->oneoverarea = 1.0f / area; + + /* + debug_printf("%s one-over-area %f area %f det %f\n", + __FUNCTION__, setup->oneoverarea, area, det ); + */ + if (util_is_inf_or_nan(setup->oneoverarea)) + return FALSE; + } + + /* We need to know if this is a front or back-facing triangle for: + * - the GLSL gl_FrontFacing fragment attribute (bool) + * - two-sided stencil test + */ + setup->quad.input.facing = (det > 0.0) ^ (setup->llvmpipe->rasterizer->front_winding == PIPE_WINDING_CW); + + return TRUE; +} + + +/** + * Compute a0 for a constant-valued coefficient (GL_FLAT shading). + * The value value comes from vertex[slot][i]. + * The result will be put into setup->coef[slot].a0[i]. + * \param slot which attribute slot + * \param i which component of the slot (0..3) + */ +static void const_coeff( struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + assert(i <= 3); + + coef->dadx[i] = 0; + coef->dady[i] = 0; + + /* need provoking vertex info! + */ + coef->a0[i] = setup->vprovoke[vertSlot][i]; +} + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a triangle. + */ +static void tri_linear_coeff( struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i]; + float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; + float a = setup->ebot.dy * majda - botda * setup->emaj.dy; + float b = setup->emaj.dx * botda - majda * setup->ebot.dx; + float dadx = a * setup->oneoverarea; + float dady = b * setup->oneoverarea; + + assert(i <= 3); + + coef->dadx[i] = dadx; + coef->dady[i] = dady; + + /* calculate a0 as the value which would be sampled for the + * fragment at (0,0), taking into account that we want to sample at + * pixel centers, in other words (0.5, 0.5). + * + * this is neat but unfortunately not a good way to do things for + * triangles with very large values of dadx or dady as it will + * result in the subtraction and re-addition from a0 of a very + * large number, which means we'll end up loosing a lot of the + * fractional bits and precision from a0. the way to fix this is + * to define a0 as the sample at a pixel center somewhere near vmin + * instead - i'll switch to this later. + */ + coef->a0[i] = (setup->vmin[vertSlot][i] - + (dadx * (setup->vmin[0][0] - 0.5f) + + dady * (setup->vmin[0][1] - 0.5f))); + + /* + debug_printf("attr[%d].%c: %f dx:%f dy:%f\n", + slot, "xyzw"[i], + setup->coef[slot].a0[i], + setup->coef[slot].dadx[i], + setup->coef[slot].dady[i]); + */ +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a triangle. + * We basically multiply the vertex value by 1/w before computing + * the plane coefficients (a0, dadx, dady). + * Later, when we compute the value at a particular fragment position we'll + * divide the interpolated value by the interpolated W at that fragment. + */ +static void tri_persp_coeff( struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + /* premultiply by 1/w (v[0][3] is always W): + */ + float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3]; + float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3]; + float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3]; + float botda = mida - mina; + float majda = maxa - mina; + float a = setup->ebot.dy * majda - botda * setup->emaj.dy; + float b = setup->emaj.dx * botda - majda * setup->ebot.dx; + float dadx = a * setup->oneoverarea; + float dady = b * setup->oneoverarea; + + /* + debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i, + setup->vmin[vertSlot][i], + setup->vmid[vertSlot][i], + setup->vmax[vertSlot][i] + ); + */ + assert(i <= 3); + + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (mina - + (dadx * (setup->vmin[0][0] - 0.5f) + + dady * (setup->vmin[0][1] - 0.5f))); +} + + +/** + * Special coefficient setup for gl_FragCoord. + * X and Y are trivial, though Y has to be inverted for OpenGL. + * Z and W are copied from posCoef which should have already been computed. + * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. + */ +static void +setup_fragcoord_coeff(struct setup_context *setup, uint slot) +{ + /*X*/ + setup->coef[slot].a0[0] = 0; + setup->coef[slot].dadx[0] = 1.0; + setup->coef[slot].dady[0] = 0.0; + /*Y*/ + setup->coef[slot].a0[1] = 0.0; + setup->coef[slot].dadx[1] = 0.0; + setup->coef[slot].dady[1] = 1.0; + /*Z*/ + setup->coef[slot].a0[2] = setup->posCoef.a0[2]; + setup->coef[slot].dadx[2] = setup->posCoef.dadx[2]; + setup->coef[slot].dady[2] = setup->posCoef.dady[2]; + /*W*/ + setup->coef[slot].a0[3] = setup->posCoef.a0[3]; + setup->coef[slot].dadx[3] = setup->posCoef.dadx[3]; + setup->coef[slot].dady[3] = setup->posCoef.dady[3]; +} + + + +/** + * Compute the setup->coef[] array dadx, dady, a0 values. + * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. + */ +static void setup_tri_coefficients( struct setup_context *setup ) +{ + struct llvmpipe_context *llvmpipe = setup->llvmpipe; + const struct lp_fragment_shader *lpfs = llvmpipe->fs; + const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); + uint fragSlot; + + /* z and w are done by linear interpolation: + */ + tri_linear_coeff(setup, &setup->posCoef, 0, 2); + tri_linear_coeff(setup, &setup->posCoef, 0, 3); + + /* setup interpolation for all the remaining attributes: + */ + for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { + const uint vertSlot = vinfo->attrib[fragSlot].src_index; + uint j; + + switch (vinfo->attrib[fragSlot].interp_mode) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + tri_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + tri_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + setup_fragcoord_coeff(setup, fragSlot); + break; + default: + assert(0); + } + + if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { + setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; + setup->coef[fragSlot].dadx[0] = 0.0; + setup->coef[fragSlot].dady[0] = 0.0; + } + } +} + + + +static void setup_tri_edges( struct setup_context *setup ) +{ + float vmin_x = setup->vmin[0][0] + 0.5f; + float vmid_x = setup->vmid[0][0] + 0.5f; + + float vmin_y = setup->vmin[0][1] - 0.5f; + float vmid_y = setup->vmid[0][1] - 0.5f; + float vmax_y = setup->vmax[0][1] - 0.5f; + + setup->emaj.sy = ceilf(vmin_y); + setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy); + setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; + setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; + + setup->etop.sy = ceilf(vmid_y); + setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy); + setup->etop.dxdy = setup->etop.dx / setup->etop.dy; + setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; + + setup->ebot.sy = ceilf(vmin_y); + setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy); + setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; + setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; +} + + +/** + * Render the upper or lower half of a triangle. + * Scissoring/cliprect is applied here too. + */ +static void subtriangle( struct setup_context *setup, + struct edge *eleft, + struct edge *eright, + unsigned lines ) +{ + const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect; + const int minx = (int) cliprect->minx; + const int maxx = (int) cliprect->maxx; + const int miny = (int) cliprect->miny; + const int maxy = (int) cliprect->maxy; + int y, start_y, finish_y; + int sy = (int)eleft->sy; + + assert((int)eleft->sy == (int) eright->sy); + + /* clip top/bottom */ + start_y = sy; + finish_y = sy + lines; + + if (start_y < miny) + start_y = miny; + + if (finish_y > maxy) + finish_y = maxy; + + start_y -= sy; + finish_y -= sy; + + /* + debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); + */ + + for (y = start_y; y < finish_y; y++) { + + /* avoid accumulating adds as floats don't have the precision to + * accurately iterate large triangle edges that way. luckily we + * can just multiply these days. + * + * this is all drowned out by the attribute interpolation anyway. + */ + int left = (int)(eleft->sx + y * eleft->dxdy); + int right = (int)(eright->sx + y * eright->dxdy); + + /* clip left/right */ + if (left < minx) + left = minx; + if (right > maxx) + right = maxx; + + if (left < right) { + int _y = sy + y; + if (block(_y) != setup->span.y) { + flush_spans(setup); + setup->span.y = block(_y); + } + + setup->span.left[_y&1] = left; + setup->span.right[_y&1] = right; + setup->span.y_flags |= 1<<(_y&1); + } + } + + + /* save the values so that emaj can be restarted: + */ + eleft->sx += lines * eleft->dxdy; + eright->sx += lines * eright->dxdy; + eleft->sy += lines; + eright->sy += lines; +} + + +/** + * Recalculate prim's determinant. This is needed as we don't have + * get this information through the vbuf_render interface & we must + * calculate it here. + */ +static float +calc_det( const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0][0] - v2[0][0]; + const float ey = v0[0][1] - v2[0][1]; + const float fx = v1[0][0] - v2[0][0]; + const float fy = v1[0][1] - v2[0][1]; + + /* det = cross(e,f).z */ + return ex * fy - ey * fx; +} + + +/** + * Do setup for triangle rasterization, then render the triangle. + */ +void setup_tri( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ) +{ + float det; + +#if DEBUG_VERTS + debug_printf("Setup triangle:\n"); + print_vertex(setup, v0); + print_vertex(setup, v1); + print_vertex(setup, v2); +#endif + + if (setup->llvmpipe->no_rast) + return; + + det = calc_det(v0, v1, v2); + /* + debug_printf("%s\n", __FUNCTION__ ); + */ + +#if DEBUG_FRAGS + setup->numFragsEmitted = 0; + setup->numFragsWritten = 0; +#endif + + if (cull_tri( setup, det )) + return; + + if (!setup_sort_vertices( setup, det, v0, v1, v2 )) + return; + setup_tri_coefficients( setup ); + setup_tri_edges( setup ); + + setup->quad.input.prim = QUAD_PRIM_TRI; + + setup->span.y = 0; + setup->span.y_flags = 0; + setup->span.right[0] = 0; + setup->span.right[1] = 0; + /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ + + /* init_constant_attribs( setup ); */ + + if (setup->oneoverarea < 0.0) { + /* emaj on left: + */ + subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); + subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); + } + else { + /* emaj on right: + */ + subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); + subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); + } + + flush_spans( setup ); + + WAIT_FOR_COMPLETION(setup); + +#if DEBUG_FRAGS + printf("Tri: %u frags emitted, %u written\n", + setup->numFragsEmitted, + setup->numFragsWritten); +#endif +} + + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a line. + */ +static void +line_linear_coeff(const struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i]; + const float dadx = da * setup->emaj.dx * setup->oneoverarea; + const float dady = da * setup->emaj.dy * setup->oneoverarea; + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (setup->vmin[vertSlot][i] - + (dadx * (setup->vmin[0][0] - 0.5f) + + dady * (setup->vmin[0][1] - 0.5f))); +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a line. + */ +static void +line_persp_coeff(const struct setup_context *setup, + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + /* XXX double-check/verify this arithmetic */ + const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3]; + const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3]; + const float da = a1 - a0; + const float dadx = da * setup->emaj.dx * setup->oneoverarea; + const float dady = da * setup->emaj.dy * setup->oneoverarea; + coef->dadx[i] = dadx; + coef->dady[i] = dady; + coef->a0[i] = (setup->vmin[vertSlot][i] - + (dadx * (setup->vmin[0][0] - 0.5f) + + dady * (setup->vmin[0][1] - 0.5f))); +} + + +/** + * Compute the setup->coef[] array dadx, dady, a0 values. + * Must be called after setup->vmin,vmax are initialized. + */ +static INLINE boolean +setup_line_coefficients(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]) +{ + struct llvmpipe_context *llvmpipe = setup->llvmpipe; + const struct lp_fragment_shader *lpfs = llvmpipe->fs; + const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); + uint fragSlot; + float area; + + /* use setup->vmin, vmax to point to vertices */ + if (llvmpipe->rasterizer->flatshade_first) + setup->vprovoke = v0; + else + setup->vprovoke = v1; + setup->vmin = v0; + setup->vmax = v1; + + setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; + setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; + + /* NOTE: this is not really area but something proportional to it */ + area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; + if (area == 0.0f || util_is_inf_or_nan(area)) + return FALSE; + setup->oneoverarea = 1.0f / area; + + /* z and w are done by linear interpolation: + */ + line_linear_coeff(setup, &setup->posCoef, 0, 2); + line_linear_coeff(setup, &setup->posCoef, 0, 3); + + /* setup interpolation for all the remaining attributes: + */ + for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { + const uint vertSlot = vinfo->attrib[fragSlot].src_index; + uint j; + + switch (vinfo->attrib[fragSlot].interp_mode) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + setup_fragcoord_coeff(setup, fragSlot); + break; + default: + assert(0); + } + + if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { + setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; + setup->coef[fragSlot].dadx[0] = 0.0; + setup->coef[fragSlot].dady[0] = 0.0; + } + } + return TRUE; +} + + +/** + * Plot a pixel in a line segment. + */ +static INLINE void +plot(struct setup_context *setup, int x, int y) +{ + const int iy = y & 1; + const int ix = x & 1; + const int quadX = x - ix; + const int quadY = y - iy; + const int mask = (1 << ix) << (2 * iy); + + if (quadX != setup->quad.input.x0 || + quadY != setup->quad.input.y0) + { + /* flush prev quad, start new quad */ + + if (setup->quad.input.x0 != -1) + CLIP_EMIT_QUAD(setup); + + setup->quad.input.x0 = quadX; + setup->quad.input.y0 = quadY; + setup->quad.inout.mask = 0x0; + } + + setup->quad.inout.mask |= mask; +} + + +/** + * Do setup for line rasterization, then render the line. + * Single-pixel width, no stipple, etc. We rely on the 'draw' module + * to handle stippling and wide lines. + */ +void +setup_line(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]) +{ + int x0 = (int) v0[0][0]; + int x1 = (int) v1[0][0]; + int y0 = (int) v0[0][1]; + int y1 = (int) v1[0][1]; + int dx = x1 - x0; + int dy = y1 - y0; + int xstep, ystep; + +#if DEBUG_VERTS + debug_printf("Setup line:\n"); + print_vertex(setup, v0); + print_vertex(setup, v1); +#endif + + if (setup->llvmpipe->no_rast) + return; + + if (dx == 0 && dy == 0) + return; + + if (!setup_line_coefficients(setup, v0, v1)) + return; + + assert(v0[0][0] < 1.0e9); + assert(v0[0][1] < 1.0e9); + assert(v1[0][0] < 1.0e9); + assert(v1[0][1] < 1.0e9); + + if (dx < 0) { + dx = -dx; /* make positive */ + xstep = -1; + } + else { + xstep = 1; + } + + if (dy < 0) { + dy = -dy; /* make positive */ + ystep = -1; + } + else { + ystep = 1; + } + + assert(dx >= 0); + assert(dy >= 0); + + setup->quad.input.x0 = setup->quad.input.y0 = -1; + setup->quad.inout.mask = 0x0; + setup->quad.input.prim = QUAD_PRIM_LINE; + /* XXX temporary: set coverage to 1.0 so the line appears + * if AA mode happens to be enabled. + */ + setup->quad.input.coverage[0] = + setup->quad.input.coverage[1] = + setup->quad.input.coverage[2] = + setup->quad.input.coverage[3] = 1.0; + + if (dx > dy) { + /*** X-major line ***/ + int i; + const int errorInc = dy + dy; + int error = errorInc - dx; + const int errorDec = error - dx; + + for (i = 0; i < dx; i++) { + plot(setup, x0, y0); + + x0 += xstep; + if (error < 0) { + error += errorInc; + } + else { + error += errorDec; + y0 += ystep; + } + } + } + else { + /*** Y-major line ***/ + int i; + const int errorInc = dx + dx; + int error = errorInc - dy; + const int errorDec = error - dy; + + for (i = 0; i < dy; i++) { + plot(setup, x0, y0); + + y0 += ystep; + if (error < 0) { + error += errorInc; + } + else { + error += errorDec; + x0 += xstep; + } + } + } + + /* draw final quad */ + if (setup->quad.inout.mask) { + CLIP_EMIT_QUAD(setup); + } + + WAIT_FOR_COMPLETION(setup); +} + + +static void +point_persp_coeff(const struct setup_context *setup, + const float (*vert)[4], + struct tgsi_interp_coef *coef, + uint vertSlot, uint i) +{ + assert(i <= 3); + coef->dadx[i] = 0.0F; + coef->dady[i] = 0.0F; + coef->a0[i] = vert[vertSlot][i] * vert[0][3]; +} + + +/** + * Do setup for point rasterization, then render the point. + * Round or square points... + * XXX could optimize a lot for 1-pixel points. + */ +void +setup_point( struct setup_context *setup, + const float (*v0)[4] ) +{ + struct llvmpipe_context *llvmpipe = setup->llvmpipe; + const struct lp_fragment_shader *lpfs = llvmpipe->fs; + const int sizeAttr = setup->llvmpipe->psize_slot; + const float size + = sizeAttr > 0 ? v0[sizeAttr][0] + : setup->llvmpipe->rasterizer->point_size; + const float halfSize = 0.5F * size; + const boolean round = (boolean) setup->llvmpipe->rasterizer->point_smooth; + const float x = v0[0][0]; /* Note: data[0] is always position */ + const float y = v0[0][1]; + const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe); + uint fragSlot; + +#if DEBUG_VERTS + debug_printf("Setup point:\n"); + print_vertex(setup, v0); +#endif + + if (llvmpipe->no_rast) + return; + + /* For points, all interpolants are constant-valued. + * However, for point sprites, we'll need to setup texcoords appropriately. + * XXX: which coefficients are the texcoords??? + * We may do point sprites as textured quads... + * + * KW: We don't know which coefficients are texcoords - ultimately + * the choice of what interpolation mode to use for each attribute + * should be determined by the fragment program, using + * per-attribute declaration statements that include interpolation + * mode as a parameter. So either the fragment program will have + * to be adjusted for pointsprite vs normal point behaviour, or + * otherwise a special interpolation mode will have to be defined + * which matches the required behaviour for point sprites. But - + * the latter is not a feature of normal hardware, and as such + * probably should be ruled out on that basis. + */ + setup->vprovoke = v0; + + /* setup Z, W */ + const_coeff(setup, &setup->posCoef, 0, 2); + const_coeff(setup, &setup->posCoef, 0, 3); + + for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) { + const uint vertSlot = vinfo->attrib[fragSlot].src_index; + uint j; + + switch (vinfo->attrib[fragSlot].interp_mode) { + case INTERP_CONSTANT: + /* fall-through */ + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + point_persp_coeff(setup, setup->vprovoke, + &setup->coef[fragSlot], vertSlot, j); + break; + case INTERP_POS: + setup_fragcoord_coeff(setup, fragSlot); + break; + default: + assert(0); + } + + if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { + setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing; + setup->coef[fragSlot].dadx[0] = 0.0; + setup->coef[fragSlot].dady[0] = 0.0; + } + } + + setup->quad.input.prim = QUAD_PRIM_POINT; + + if (halfSize <= 0.5 && !round) { + /* special case for 1-pixel points */ + const int ix = ((int) x) & 1; + const int iy = ((int) y) & 1; + setup->quad.input.x0 = (int) x - ix; + setup->quad.input.y0 = (int) y - iy; + setup->quad.inout.mask = (1 << ix) << (2 * iy); + CLIP_EMIT_QUAD(setup); + } + else { + if (round) { + /* rounded points */ + const int ixmin = block((int) (x - halfSize)); + const int ixmax = block((int) (x + halfSize)); + const int iymin = block((int) (y - halfSize)); + const int iymax = block((int) (y + halfSize)); + const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ + const float rmax = halfSize + 0.7071F; + const float rmin2 = MAX2(0.0F, rmin * rmin); + const float rmax2 = rmax * rmax; + const float cscale = 1.0F / (rmax2 - rmin2); + int ix, iy; + + for (iy = iymin; iy <= iymax; iy += 2) { + for (ix = ixmin; ix <= ixmax; ix += 2) { + float dx, dy, dist2, cover; + + setup->quad.inout.mask = 0x0; + + dx = (ix + 0.5f) - x; + dy = (iy + 0.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f); + setup->quad.inout.mask |= MASK_TOP_LEFT; + } + + dx = (ix + 1.5f) - x; + dy = (iy + 0.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f); + setup->quad.inout.mask |= MASK_TOP_RIGHT; + } + + dx = (ix + 0.5f) - x; + dy = (iy + 1.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f); + setup->quad.inout.mask |= MASK_BOTTOM_LEFT; + } + + dx = (ix + 1.5f) - x; + dy = (iy + 1.5f) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f); + setup->quad.inout.mask |= MASK_BOTTOM_RIGHT; + } + + if (setup->quad.inout.mask) { + setup->quad.input.x0 = ix; + setup->quad.input.y0 = iy; + CLIP_EMIT_QUAD(setup); + } + } + } + } + else { + /* square points */ + const int xmin = (int) (x + 0.75 - halfSize); + const int ymin = (int) (y + 0.25 - halfSize); + const int xmax = xmin + (int) size; + const int ymax = ymin + (int) size; + /* XXX could apply scissor to xmin,ymin,xmax,ymax now */ + const int ixmin = block(xmin); + const int ixmax = block(xmax - 1); + const int iymin = block(ymin); + const int iymax = block(ymax - 1); + int ix, iy; + + /* + debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax); + */ + for (iy = iymin; iy <= iymax; iy += 2) { + uint rowMask = 0xf; + if (iy < ymin) { + /* above the top edge */ + rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); + } + if (iy + 1 >= ymax) { + /* below the bottom edge */ + rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT); + } + + for (ix = ixmin; ix <= ixmax; ix += 2) { + uint mask = rowMask; + + if (ix < xmin) { + /* fragment is past left edge of point, turn off left bits */ + mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); + } + if (ix + 1 >= xmax) { + /* past the right edge */ + mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT); + } + + setup->quad.inout.mask = mask; + setup->quad.input.x0 = ix; + setup->quad.input.y0 = iy; + CLIP_EMIT_QUAD(setup); + } + } + } + } + + WAIT_FOR_COMPLETION(setup); +} + +void setup_prepare( struct setup_context *setup ) +{ + struct llvmpipe_context *lp = setup->llvmpipe; + unsigned i; + + if (lp->dirty) { + llvmpipe_update_derived(lp); + } + + /* Note: nr_attrs is only used for debugging (vertex printing) */ + setup->quad.nr_attrs = draw_num_vs_outputs(lp->draw); + + for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { + lp->quad[i].first->begin( lp->quad[i].first ); + } + + if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES && + lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && + lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { + /* we'll do culling */ + setup->winding = lp->rasterizer->cull_mode; + } + else { + /* 'draw' will do culling */ + setup->winding = PIPE_WINDING_NONE; + } +} + + + +void setup_destroy_context( struct setup_context *setup ) +{ + FREE( setup ); +} + + +/** + * Create a new primitive setup/render stage. + */ +struct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe ) +{ + struct setup_context *setup = CALLOC_STRUCT(setup_context); +#if SP_NUM_QUAD_THREADS > 1 + uint i; +#endif + + setup->llvmpipe = llvmpipe; + + setup->quad.coef = setup->coef; + setup->quad.posCoef = &setup->posCoef; + +#if SP_NUM_QUAD_THREADS > 1 + setup->que.first = 0; + setup->que.last = 0; + pipe_mutex_init( setup->que.que_mutex ); + pipe_condvar_init( setup->que.que_notfull_condvar ); + pipe_condvar_init( setup->que.que_notempty_condvar ); + setup->que.jobs_added = 0; + setup->que.jobs_done = 0; + pipe_condvar_init( setup->que.que_done_condvar ); + for (i = 0; i < SP_NUM_QUAD_THREADS; i++) { + setup->threads[i].setup = setup; + setup->threads[i].id = i; + setup->threads[i].handle = pipe_thread_create( quad_thread, &setup->threads[i] ); + } +#endif + + return setup; +} + diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h new file mode 100644 index 0000000000..0e84dfc615 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -0,0 +1,53 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +#ifndef SP_SETUP_H +#define SP_SETUP_H + +struct setup_context; +struct llvmpipe_context; + +void +setup_tri( struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4], + const float (*v2)[4] ); + +void +setup_line(struct setup_context *setup, + const float (*v0)[4], + const float (*v1)[4]); + +void +setup_point( struct setup_context *setup, + const float (*v0)[4] ); + + +struct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe ); +void setup_prepare( struct setup_context *setup ); +void setup_destroy_context( struct setup_context *setup ); + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h new file mode 100644 index 0000000000..778b3a5a68 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -0,0 +1,206 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_STATE_H +#define SP_STATE_H + +#include "pipe/p_state.h" +#include "tgsi/tgsi_scan.h" + + +#define SP_NEW_VIEWPORT 0x1 +#define SP_NEW_RASTERIZER 0x2 +#define SP_NEW_FS 0x4 +#define SP_NEW_BLEND 0x8 +#define SP_NEW_CLIP 0x10 +#define SP_NEW_SCISSOR 0x20 +#define SP_NEW_STIPPLE 0x40 +#define SP_NEW_FRAMEBUFFER 0x80 +#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100 +#define SP_NEW_CONSTANTS 0x200 +#define SP_NEW_SAMPLER 0x400 +#define SP_NEW_TEXTURE 0x800 +#define SP_NEW_VERTEX 0x1000 +#define SP_NEW_VS 0x2000 +#define SP_NEW_QUERY 0x4000 + + +struct tgsi_sampler; +struct tgsi_exec_machine; +struct vertex_info; + + +/** + * Subclass of pipe_shader_state (though it doesn't really need to be). + * + * This is starting to look an awful lot like a quad pipeline stage... + */ +struct lp_fragment_shader { + struct pipe_shader_state shader; + + struct tgsi_shader_info info; + + void (*prepare)( const struct lp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct tgsi_sampler **samplers); + + /* Run the shader - this interface will get cleaned up in the + * future: + */ + unsigned (*run)( const struct lp_fragment_shader *shader, + struct tgsi_exec_machine *machine, + struct quad_header *quad ); + + + void (*delete)( struct lp_fragment_shader * ); +}; + + +/** Subclass of pipe_shader_state */ +struct lp_vertex_shader { + struct pipe_shader_state shader; + struct draw_vertex_shader *draw_data; +}; + + + +void * +llvmpipe_create_blend_state(struct pipe_context *, + const struct pipe_blend_state *); +void llvmpipe_bind_blend_state(struct pipe_context *, + void *); +void llvmpipe_delete_blend_state(struct pipe_context *, + void *); + +void * +llvmpipe_create_sampler_state(struct pipe_context *, + const struct pipe_sampler_state *); +void llvmpipe_bind_sampler_states(struct pipe_context *, unsigned, void **); +void llvmpipe_delete_sampler_state(struct pipe_context *, void *); + +void * +llvmpipe_create_depth_stencil_state(struct pipe_context *, + const struct pipe_depth_stencil_alpha_state *); +void llvmpipe_bind_depth_stencil_state(struct pipe_context *, void *); +void llvmpipe_delete_depth_stencil_state(struct pipe_context *, void *); + +void * +llvmpipe_create_rasterizer_state(struct pipe_context *, + const struct pipe_rasterizer_state *); +void llvmpipe_bind_rasterizer_state(struct pipe_context *, void *); +void llvmpipe_delete_rasterizer_state(struct pipe_context *, void *); + +void llvmpipe_set_framebuffer_state( struct pipe_context *, + const struct pipe_framebuffer_state * ); + +void llvmpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ); + +void llvmpipe_set_clip_state( struct pipe_context *, + const struct pipe_clip_state * ); + +void llvmpipe_set_constant_buffer(struct pipe_context *, + uint shader, uint index, + const struct pipe_constant_buffer *buf); + +void *llvmpipe_create_fs_state(struct pipe_context *, + const struct pipe_shader_state *); +void llvmpipe_bind_fs_state(struct pipe_context *, void *); +void llvmpipe_delete_fs_state(struct pipe_context *, void *); +void *llvmpipe_create_vs_state(struct pipe_context *, + const struct pipe_shader_state *); +void llvmpipe_bind_vs_state(struct pipe_context *, void *); +void llvmpipe_delete_vs_state(struct pipe_context *, void *); + +void llvmpipe_set_polygon_stipple( struct pipe_context *, + const struct pipe_poly_stipple * ); + +void llvmpipe_set_scissor_state( struct pipe_context *, + const struct pipe_scissor_state * ); + +void llvmpipe_set_sampler_textures( struct pipe_context *, + unsigned num, + struct pipe_texture ** ); + +void llvmpipe_set_viewport_state( struct pipe_context *, + const struct pipe_viewport_state * ); + +void llvmpipe_set_vertex_elements(struct pipe_context *, + unsigned count, + const struct pipe_vertex_element *); + +void llvmpipe_set_vertex_buffers(struct pipe_context *, + unsigned count, + const struct pipe_vertex_buffer *); + + +void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ); + + +boolean llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count); + +boolean llvmpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count); +boolean +llvmpipe_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned min_index, + unsigned max_index, + unsigned mode, unsigned start, unsigned count); + +void +llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags); + + +void +llvmpipe_map_transfers(struct llvmpipe_context *lp); + +void +llvmpipe_unmap_transfers(struct llvmpipe_context *lp); + +void +llvmpipe_map_texture_surfaces(struct llvmpipe_context *lp); + +void +llvmpipe_unmap_texture_surfaces(struct llvmpipe_context *lp); + + +struct vertex_info * +llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe); + +struct vertex_info * +llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe); + + +#endif diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c new file mode 100644 index 0000000000..420615bd5b --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c @@ -0,0 +1,98 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_state.h" + + +void * +llvmpipe_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + return mem_dup(blend, sizeof(*blend)); +} + +void llvmpipe_bind_blend_state( struct pipe_context *pipe, + void *blend ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + llvmpipe->blend = (const struct pipe_blend_state *)blend; + + llvmpipe->dirty |= SP_NEW_BLEND; +} + +void llvmpipe_delete_blend_state(struct pipe_context *pipe, + void *blend) +{ + FREE( blend ); +} + + +void llvmpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + llvmpipe->blend_color = *blend_color; + + llvmpipe->dirty |= SP_NEW_BLEND; +} + + +/** XXX move someday? Or consolidate all these simple state setters + * into one file. + */ + + +void * +llvmpipe_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + return mem_dup(depth_stencil, sizeof(*depth_stencil)); +} + +void +llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + + llvmpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA; +} + +void +llvmpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth) +{ + FREE( depth ); +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_clip.c b/src/gallium/drivers/llvmpipe/lp_state_clip.c new file mode 100644 index 0000000000..b5408f787d --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_clip.c @@ -0,0 +1,79 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ +#include "lp_context.h" +#include "lp_state.h" +#include "draw/draw_context.h" + + +void llvmpipe_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + /* pass the clip state to the draw module */ + draw_set_clip_state(llvmpipe->draw, clip); +} + + +void llvmpipe_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + /* pass the viewport info to the draw module */ + draw_set_viewport_state(llvmpipe->draw, viewport); + + llvmpipe->viewport = *viewport; /* struct copy */ + llvmpipe->dirty |= SP_NEW_VIEWPORT; +} + + +void llvmpipe_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + draw_flush(llvmpipe->draw); + + llvmpipe->scissor = *scissor; /* struct copy */ + llvmpipe->dirty |= SP_NEW_SCISSOR; +} + + +void llvmpipe_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + draw_flush(llvmpipe->draw); + + llvmpipe->poly_stipple = *stipple; /* struct copy */ + llvmpipe->dirty |= SP_NEW_STIPPLE; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c new file mode 100644 index 0000000000..3fd3c4078b --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -0,0 +1,211 @@ +/************************************************************************** + * + * Copyright 2003 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_math.h" +#include "util/u_memory.h" +#include "pipe/p_shader_tokens.h" +#include "draw/draw_context.h" +#include "draw/draw_vertex.h" +#include "draw/draw_private.h" +#include "lp_context.h" +#include "lp_state.h" + + +/** + * Mark the current vertex layout as "invalid". + * We'll validate the vertex layout later, when we start to actually + * render a point or line or tri. + */ +static void +invalidate_vertex_layout(struct llvmpipe_context *llvmpipe) +{ + llvmpipe->vertex_info.num_attribs = 0; +} + + +/** + * The vertex info describes how to convert the post-transformed vertices + * (simple float[][4]) used by the 'draw' module into vertices for + * rasterization. + * + * This function validates the vertex layout and returns a pointer to a + * vertex_info object. + */ +struct vertex_info * +llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe) +{ + struct vertex_info *vinfo = &llvmpipe->vertex_info; + + if (vinfo->num_attribs == 0) { + /* compute vertex layout now */ + const struct lp_fragment_shader *lpfs = llvmpipe->fs; + const enum interp_mode colorInterp + = llvmpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; + uint i; + + if (llvmpipe->vbuf) { + /* if using the post-transform vertex buffer, tell draw_vbuf to + * simply emit the whole post-xform vertex as-is: + */ + struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf; + const uint num = draw_num_vs_outputs(llvmpipe->draw); + uint i; + + /* No longer any need to try and emit draw vertex_header info. + */ + vinfo_vbuf->num_attribs = 0; + for (i = 0; i < num; i++) { + draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i); + } + draw_compute_vertex_size(vinfo_vbuf); + } + + /* + * Loop over fragment shader inputs, searching for the matching output + * from the vertex shader. + */ + vinfo->num_attribs = 0; + for (i = 0; i < lpfs->info.num_inputs; i++) { + int src; + switch (lpfs->info.input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + src = draw_find_vs_output(llvmpipe->draw, + TGSI_SEMANTIC_POSITION, 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src); + break; + + case TGSI_SEMANTIC_COLOR: + src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_COLOR, + lpfs->info.input_semantic_index[i]); + draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); + break; + + case TGSI_SEMANTIC_FOG: + src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_FOG, 0); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); + break; + + case TGSI_SEMANTIC_GENERIC: + case TGSI_SEMANTIC_FACE: + /* this includes texcoords and varying vars */ + src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_GENERIC, + lpfs->info.input_semantic_index[i]); + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); + break; + + default: + assert(0); + } + } + + llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw, + TGSI_SEMANTIC_PSIZE, 0); + if (llvmpipe->psize_slot > 0) { + draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, + llvmpipe->psize_slot); + } + + draw_compute_vertex_size(vinfo); + } + + return vinfo; +} + + +/** + * Called from vbuf module. + * + * Note that there's actually two different vertex layouts in llvmpipe. + * + * The normal one is computed in llvmpipe_get_vertex_info() above and is + * used by the point/line/tri "setup" code. + * + * The other one (this one) is only used by the vbuf module (which is + * not normally used by default but used in testing). For the vbuf module, + * we basically want to pass-through the draw module's vertex layout as-is. + * When the llvmpipe vbuf code begins drawing, the normal vertex layout + * will come into play again. + */ +struct vertex_info * +llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe) +{ + (void) llvmpipe_get_vertex_info(llvmpipe); + return &llvmpipe->vertex_info_vbuf; +} + + +/** + * Recompute cliprect from scissor bounds, scissor enable and surface size. + */ +static void +compute_cliprect(struct llvmpipe_context *lp) +{ + uint surfWidth = lp->framebuffer.width; + uint surfHeight = lp->framebuffer.height; + + if (lp->rasterizer->scissor) { + /* clip to scissor rect */ + lp->cliprect.minx = MAX2(lp->scissor.minx, 0); + lp->cliprect.miny = MAX2(lp->scissor.miny, 0); + lp->cliprect.maxx = MIN2(lp->scissor.maxx, surfWidth); + lp->cliprect.maxy = MIN2(lp->scissor.maxy, surfHeight); + } + else { + /* clip to surface bounds */ + lp->cliprect.minx = 0; + lp->cliprect.miny = 0; + lp->cliprect.maxx = surfWidth; + lp->cliprect.maxy = surfHeight; + } +} + + +/* Hopefully this will remain quite simple, otherwise need to pull in + * something like the state tracker mechanism. + */ +void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe ) +{ + if (llvmpipe->dirty & (SP_NEW_RASTERIZER | + SP_NEW_FS | + SP_NEW_VS)) + invalidate_vertex_layout( llvmpipe ); + + if (llvmpipe->dirty & (SP_NEW_SCISSOR | + SP_NEW_DEPTH_STENCIL_ALPHA | + SP_NEW_FRAMEBUFFER)) + compute_cliprect(llvmpipe); + + if (llvmpipe->dirty & (SP_NEW_BLEND | + SP_NEW_DEPTH_STENCIL_ALPHA | + SP_NEW_FRAMEBUFFER | + SP_NEW_RASTERIZER | + SP_NEW_FS | + SP_NEW_QUERY)) + lp_build_quad_pipeline(llvmpipe); + + llvmpipe->dirty = 0; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c new file mode 100644 index 0000000000..dcc73f44e8 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -0,0 +1,169 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_fs.h" + +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "pipe/internal/p_winsys_screen.h" +#include "pipe/p_shader_tokens.h" +#include "draw/draw_context.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_scan.h" +#include "tgsi/tgsi_parse.h" + + +void * +llvmpipe_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + struct lp_fragment_shader *state; + + /* debug */ + if (llvmpipe->dump_fs) + tgsi_dump(templ->tokens, 0); + + /* codegen */ + state = llvmpipe_create_fs_llvm( llvmpipe, templ ); + if (!state) { + state = llvmpipe_create_fs_sse( llvmpipe, templ ); + if (!state) { + state = llvmpipe_create_fs_exec( llvmpipe, templ ); + } + } + + assert(state); + + /* get/save the summary info for this shader */ + tgsi_scan_shader(templ->tokens, &state->info); + + return state; +} + + +void +llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + llvmpipe->fs = (struct lp_fragment_shader *) fs; + + llvmpipe->dirty |= SP_NEW_FS; +} + + +void +llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct lp_fragment_shader *state = fs; + + assert(fs != llvmpipe_context(pipe)->fs); + + state->delete( state ); +} + + +void * +llvmpipe_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + struct lp_vertex_shader *state; + + state = CALLOC_STRUCT(lp_vertex_shader); + if (state == NULL ) + goto fail; + + /* copy shader tokens, the ones passed in will go away. + */ + state->shader.tokens = tgsi_dup_tokens(templ->tokens); + if (state->shader.tokens == NULL) + goto fail; + + state->draw_data = draw_create_vertex_shader(llvmpipe->draw, templ); + if (state->draw_data == NULL) + goto fail; + + return state; + +fail: + if (state) { + FREE( (void *)state->shader.tokens ); + FREE( state->draw_data ); + FREE( state ); + } + return NULL; +} + + +void +llvmpipe_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + llvmpipe->vs = (const struct lp_vertex_shader *)vs; + + draw_bind_vertex_shader(llvmpipe->draw, + (llvmpipe->vs ? llvmpipe->vs->draw_data : NULL)); + + llvmpipe->dirty |= SP_NEW_VS; +} + + +void +llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + struct lp_vertex_shader *state = + (struct lp_vertex_shader *)vs; + + draw_delete_vertex_shader(llvmpipe->draw, state->draw_data); + FREE( state ); +} + + + +void +llvmpipe_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + assert(shader < PIPE_SHADER_TYPES); + assert(index == 0); + + /* note: reference counting */ + pipe_buffer_reference(&llvmpipe->constants[shader].buffer, + buf ? buf->buffer : NULL); + + llvmpipe->dirty |= SP_NEW_CONSTANTS; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c new file mode 100644 index 0000000000..9e38606b14 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c @@ -0,0 +1,62 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "util/u_memory.h" +#include "lp_context.h" +#include "lp_state.h" +#include "draw/draw_context.h" + + + +void * +llvmpipe_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rast) +{ + return mem_dup(rast, sizeof(*rast)); +} + +void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + /* pass-through to draw module */ + draw_set_rasterizer_state(llvmpipe->draw, setup); + + llvmpipe->rasterizer = (struct pipe_rasterizer_state *)setup; + + llvmpipe->dirty |= SP_NEW_RASTERIZER; +} + +void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe, + void *rasterizer) +{ + FREE( rasterizer ); +} + + diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c new file mode 100644 index 0000000000..790c12302f --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -0,0 +1,117 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: + * Brian Paul + */ + +#include "util/u_memory.h" + +#include "draw/draw_context.h" + +#include "lp_context.h" +#include "lp_context.h" +#include "lp_state.h" +#include "lp_texture.h" +#include "lp_tile_cache.h" +#include "draw/draw_context.h" + + + +void * +llvmpipe_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + return mem_dup(sampler, sizeof(*sampler)); +} + + +void +llvmpipe_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + unsigned i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == llvmpipe->num_samplers && + !memcmp(llvmpipe->sampler, sampler, num * sizeof(void *))) + return; + + draw_flush(llvmpipe->draw); + + for (i = 0; i < num; ++i) + llvmpipe->sampler[i] = sampler[i]; + for (i = num; i < PIPE_MAX_SAMPLERS; ++i) + llvmpipe->sampler[i] = NULL; + + llvmpipe->num_samplers = num; + + llvmpipe->dirty |= SP_NEW_SAMPLER; +} + + +void +llvmpipe_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == llvmpipe->num_textures && + !memcmp(llvmpipe->texture, texture, num * sizeof(struct pipe_texture *))) + return; + + draw_flush(llvmpipe->draw); + + for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { + struct pipe_texture *tex = i < num ? texture[i] : NULL; + + pipe_texture_reference(&llvmpipe->texture[i], tex); + lp_tile_cache_set_texture(pipe, llvmpipe->tex_cache[i], tex); + } + + llvmpipe->num_textures = num; + + llvmpipe->dirty |= SP_NEW_TEXTURE; +} + + +void +llvmpipe_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + FREE( sampler ); +} + + + diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c new file mode 100644 index 0000000000..d71e1a7ebb --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c @@ -0,0 +1,129 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_surface.h" +#include "lp_tile_cache.h" + +#include "draw/draw_context.h" + + +/** + * XXX this might get moved someday + * Set the framebuffer surface info: color buffers, zbuffer, stencil buffer. + * Here, we flush the old surfaces and update the tile cache to point to the new + * surfaces. + */ +void +llvmpipe_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct llvmpipe_context *lp = llvmpipe_context(pipe); + uint i; + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + /* check if changing cbuf */ + if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) { + /* flush old */ + lp_flush_tile_cache(lp, lp->cbuf_cache[i]); + + /* assign new */ + lp->framebuffer.cbufs[i] = fb->cbufs[i]; + + /* update cache */ + lp_tile_cache_set_surface(lp->cbuf_cache[i], fb->cbufs[i]); + } + } + + lp->framebuffer.nr_cbufs = fb->nr_cbufs; + + /* zbuf changing? */ + if (lp->framebuffer.zsbuf != fb->zsbuf) { + /* flush old */ + lp_flush_tile_cache(lp, lp->zsbuf_cache); + + /* assign new */ + lp->framebuffer.zsbuf = fb->zsbuf; + + /* update cache */ + lp_tile_cache_set_surface(lp->zsbuf_cache, fb->zsbuf); + } + +#if 0 + /* XXX combined depth/stencil here */ + + /* sbuf changing? */ + if (lp->framebuffer.sbuf != fb->sbuf) { + /* flush old */ + lp_flush_tile_cache(lp, lp->sbuf_cache_sep); + + /* assign new */ + lp->framebuffer.sbuf = fb->sbuf; + + /* update cache */ + if (fb->sbuf != fb->zbuf) { + /* separate stencil buf */ + lp->sbuf_cache = lp->sbuf_cache_sep; + lp_tile_cache_set_surface(lp->sbuf_cache, fb->sbuf); + } + else { + /* combined depth/stencil */ + lp->sbuf_cache = lp->zbuf_cache; + lp_tile_cache_set_surface(lp->sbuf_cache, fb->sbuf); + } + } +#endif + + /* Tell draw module how deep the Z/depth buffer is */ + { + int depth_bits; + double mrd; + if (lp->framebuffer.zsbuf) { + depth_bits = pf_get_component_bits(lp->framebuffer.zsbuf->format, + PIPE_FORMAT_COMP_Z); + } + else { + depth_bits = 0; + } + if (depth_bits > 16) { + mrd = 0.0000001; + } + else { + mrd = 0.00002; + } + draw_set_mrd(lp->draw, mrd); + } + + lp->framebuffer.width = fb->width; + lp->framebuffer.height = fb->height; + + lp->dirty |= SP_NEW_FRAMEBUFFER; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c new file mode 100644 index 0000000000..68c0e94ab6 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_surface.h" + +#include "draw/draw_context.h" + + +void +llvmpipe_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *attribs) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + assert(count <= PIPE_MAX_ATTRIBS); + + memcpy(llvmpipe->vertex_element, attribs, + count * sizeof(struct pipe_vertex_element)); + llvmpipe->num_vertex_elements = count; + + llvmpipe->dirty |= SP_NEW_VERTEX; + + draw_set_vertex_elements(llvmpipe->draw, count, attribs); +} + + +void +llvmpipe_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *buffers) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + assert(count <= PIPE_MAX_ATTRIBS); + + memcpy(llvmpipe->vertex_buffer, buffers, count * sizeof(buffers[0])); + llvmpipe->num_vertex_buffers = count; + + llvmpipe->dirty |= SP_NEW_VERTEX; + + draw_set_vertex_buffers(llvmpipe->draw, count, buffers); +} diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c new file mode 100644 index 0000000000..6110b0a193 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_rect.h" +#include "lp_context.h" +#include "lp_surface.h" + + +static void +lp_surface_copy(struct pipe_context *pipe, + struct pipe_surface *dest, unsigned destx, unsigned desty, + struct pipe_surface *src, unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + util_surface_copy(pipe, FALSE, + dest, destx, desty, + src, srcx, srcy, + width, height); +} + +void +lp_init_surface_functions(struct llvmpipe_context *lp) +{ + lp->pipe.surface_copy = lp_surface_copy; + lp->pipe.surface_fill = util_surface_fill; +} diff --git a/src/gallium/drivers/llvmpipe/lp_surface.h b/src/gallium/drivers/llvmpipe/lp_surface.h new file mode 100644 index 0000000000..8ed8f553aa --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_surface.h @@ -0,0 +1,42 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell + */ + +#ifndef SP_SURFACE_H +#define SP_SURFACE_H + + +struct llvmpipe_context; + + +extern void +lp_init_surface_functions(struct llvmpipe_context *lp); + + +#endif /* SP_SURFACE_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c new file mode 100644 index 0000000000..f9f20accf9 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -0,0 +1,1295 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * Copyright 2008 VMware, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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. + * + **************************************************************************/ + +/** + * Texture sampling + * + * Authors: + * Brian Paul + */ + +#include "lp_context.h" +#include "lp_quad.h" +#include "lp_surface.h" +#include "lp_texture.h" +#include "lp_tex_sample.h" +#include "lp_tile_cache.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "util/u_math.h" +#include "util/u_memory.h" + + + +/* + * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes + * see 1-pixel bands of improperly weighted linear-filtered textures. + * The tests/texwrap.c demo is a good test. + * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. + * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). + */ +#define FRAC(f) ((f) - util_ifloor(f)) + + +/** + * Linear interpolation macro + */ +static INLINE float +lerp(float a, float v0, float v1) +{ + return v0 + a * (v1 - v0); +} + + +/** + * Do 2D/biliner interpolation of float values. + * v00, v10, v01 and v11 are typically four texture samples in a square/box. + * a and b are the horizontal and vertical interpolants. + * It's important that this function is inlined when compiled with + * optimization! If we find that's not true on some systems, convert + * to a macro. + */ +static INLINE float +lerp_2d(float a, float b, + float v00, float v10, float v01, float v11) +{ + const float temp0 = lerp(a, v00, v10); + const float temp1 = lerp(a, v01, v11); + return lerp(b, temp0, temp1); +} + + +/** + * As above, but 3D interpolation of 8 values. + */ +static INLINE float +lerp_3d(float a, float b, float c, + float v000, float v100, float v010, float v110, + float v001, float v101, float v011, float v111) +{ + const float temp0 = lerp_2d(a, b, v000, v100, v010, v110); + const float temp1 = lerp_2d(a, b, v001, v101, v011, v111); + return lerp(c, temp0, temp1); +} + + + +/** + * If A is a signed integer, A % B doesn't give the right value for A < 0 + * (in terms of texture repeat). Just casting to unsigned fixes that. + */ +#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) + + +/** + * Apply texture coord wrapping mode and return integer texture indexes + * for a vector of four texcoords (S or T or P). + * \param wrapMode PIPE_TEX_WRAP_x + * \param s the incoming texcoords + * \param size the texture image size + * \param icoord returns the integer texcoords + * \return integer texture index + */ +static INLINE void +nearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + switch (wrapMode) { + case PIPE_TEX_WRAP_REPEAT: + /* s limited to [0,1) */ + /* i limited to [0,size-1] */ + for (ch = 0; ch < 4; ch++) { + int i = util_ifloor(s[ch] * size); + icoord[ch] = REMAINDER(i, size); + } + return; + case PIPE_TEX_WRAP_CLAMP: + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + for (ch = 0; ch < 4; ch++) { + if (s[ch] <= 0.0F) + icoord[ch] = 0; + else if (s[ch] >= 1.0F) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(s[ch] * size); + } + return; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + if (s[ch] < min) + icoord[ch] = 0; + else if (s[ch] > max) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(s[ch] * size); + } + } + return; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + { + /* s limited to [min,max] */ + /* i limited to [-1, size] */ + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + if (s[ch] <= min) + icoord[ch] = -1; + else if (s[ch] >= max) + icoord[ch] = size; + else + icoord[ch] = util_ifloor(s[ch] * size); + } + } + return; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + { + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + const int flr = util_ifloor(s[ch]); + float u; + if (flr & 1) + u = 1.0F - (s[ch] - (float) flr); + else + u = s[ch] - (float) flr; + if (u < min) + icoord[ch] = 0; + else if (u > max) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(u * size); + } + } + return; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + for (ch = 0; ch < 4; ch++) { + /* s limited to [0,1] */ + /* i limited to [0,size-1] */ + const float u = fabsf(s[ch]); + if (u <= 0.0F) + icoord[ch] = 0; + else if (u >= 1.0F) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(u * size); + } + return; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = 1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + const float u = fabsf(s[ch]); + if (u < min) + icoord[ch] = 0; + else if (u > max) + icoord[ch] = size - 1; + else + icoord[ch] = util_ifloor(u * size); + } + } + return; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + { + /* s limited to [min,max] */ + /* i limited to [0, size-1] */ + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + const float u = fabsf(s[ch]); + if (u < min) + icoord[ch] = -1; + else if (u > max) + icoord[ch] = size; + else + icoord[ch] = util_ifloor(u * size); + } + } + return; + default: + assert(0); + } +} + + +/** + * Used to compute texel locations for linear sampling for four texcoords. + * \param wrapMode PIPE_TEX_WRAP_x + * \param s the texcoords + * \param size the texture image size + * \param icoord0 returns first texture indexes + * \param icoord1 returns second texture indexes (usually icoord0 + 1) + * \param w returns blend factor/weight between texture indexes + * \param icoord returns the computed integer texture coords + */ +static INLINE void +linear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + uint ch; + + switch (wrapMode) { + case PIPE_TEX_WRAP_REPEAT: + for (ch = 0; ch < 4; ch++) { + float u = s[ch] * size - 0.5F; + icoord0[ch] = REMAINDER(util_ifloor(u), size); + icoord1[ch] = REMAINDER(icoord0[ch] + 1, size); + w[ch] = FRAC(u); + } + break;; + case PIPE_TEX_WRAP_CLAMP: + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], 0.0F, 1.0F); + u = u * size - 0.5f; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); + } + break;; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], 0.0F, 1.0F); + u = u * size - 0.5f; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord0[ch] < 0) + icoord0[ch] = 0; + if (icoord1[ch] >= (int) size) + icoord1[ch] = size - 1; + w[ch] = FRAC(u); + } + break;; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + { + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], min, max); + u = u * size - 0.5f; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); + } + } + break;; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + for (ch = 0; ch < 4; ch++) { + const int flr = util_ifloor(s[ch]); + float u; + if (flr & 1) + u = 1.0F - (s[ch] - (float) flr); + else + u = s[ch] - (float) flr; + u = u * size - 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord0[ch] < 0) + icoord0[ch] = 0; + if (icoord1[ch] >= (int) size) + icoord1[ch] = size - 1; + w[ch] = FRAC(u); + } + break;; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + for (ch = 0; ch < 4; ch++) { + float u = fabsf(s[ch]); + if (u >= 1.0F) + u = (float) size; + else + u *= size; + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); + } + break;; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + for (ch = 0; ch < 4; ch++) { + float u = fabsf(s[ch]); + if (u >= 1.0F) + u = (float) size; + else + u *= size; + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord0[ch] < 0) + icoord0[ch] = 0; + if (icoord1[ch] >= (int) size) + icoord1[ch] = size - 1; + w[ch] = FRAC(u); + } + break;; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + { + const float min = -1.0F / (2.0F * size); + const float max = 1.0F - min; + for (ch = 0; ch < 4; ch++) { + float u = fabsf(s[ch]); + if (u <= min) + u = min * size; + else if (u >= max) + u = max * size; + else + u *= size; + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); + } + } + break;; + default: + assert(0); + } +} + + +/** + * For RECT textures / unnormalized texcoords + * Only a subset of wrap modes supported. + */ +static INLINE void +nearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + switch (wrapMode) { + case PIPE_TEX_WRAP_CLAMP: + for (ch = 0; ch < 4; ch++) { + int i = util_ifloor(s[ch]); + icoord[ch]= CLAMP(i, 0, (int) size-1); + } + return; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + /* fall-through */ + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + for (ch = 0; ch < 4; ch++) { + icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) ); + } + return; + default: + assert(0); + } +} + + +/** + * For RECT textures / unnormalized texcoords. + * Only a subset of wrap modes supported. + */ +static INLINE void +linear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + uint ch; + switch (wrapMode) { + case PIPE_TEX_WRAP_CLAMP: + for (ch = 0; ch < 4; ch++) { + /* Not exactly what the spec says, but it matches NVIDIA output */ + float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f); + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + w[ch] = FRAC(u); + } + return; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + /* fall-through */ + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F); + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord1[ch] > (int) size - 1) + icoord1[ch] = size - 1; + w[ch] = FRAC(u); + } + break; + default: + assert(0); + } +} + + +static unsigned +choose_cube_face(float rx, float ry, float rz, float *newS, float *newT) +{ + /* + major axis + direction target sc tc ma + ---------- ------------------------------- --- --- --- + +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx + -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx + +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry + -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry + +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz + -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz + */ + const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); + unsigned face; + float sc, tc, ma; + + if (arx > ary && arx > arz) { + if (rx >= 0.0F) { + face = PIPE_TEX_FACE_POS_X; + sc = -rz; + tc = -ry; + ma = arx; + } + else { + face = PIPE_TEX_FACE_NEG_X; + sc = rz; + tc = -ry; + ma = arx; + } + } + else if (ary > arx && ary > arz) { + if (ry >= 0.0F) { + face = PIPE_TEX_FACE_POS_Y; + sc = rx; + tc = rz; + ma = ary; + } + else { + face = PIPE_TEX_FACE_NEG_Y; + sc = rx; + tc = -rz; + ma = ary; + } + } + else { + if (rz > 0.0F) { + face = PIPE_TEX_FACE_POS_Z; + sc = rx; + tc = -ry; + ma = arz; + } + else { + face = PIPE_TEX_FACE_NEG_Z; + sc = -rx; + tc = -ry; + ma = arz; + } + } + + *newS = ( sc / ma + 1.0F ) * 0.5F; + *newT = ( tc / ma + 1.0F ) * 0.5F; + + return face; +} + + +/** + * Examine the quad's texture coordinates to compute the partial + * derivatives w.r.t X and Y, then compute lambda (level of detail). + * + * This is only done for fragment shaders, not vertex shaders. + */ +static float +compute_lambda(const struct pipe_texture *tex, + const struct pipe_sampler_state *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias) +{ + float rho, lambda; + + assert(sampler->normalized_coords); + + assert(s); + { + float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]; + float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]; + dsdx = fabsf(dsdx); + dsdy = fabsf(dsdy); + rho = MAX2(dsdx, dsdy) * tex->width[0]; + } + if (t) { + float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; + float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]; + float max; + dtdx = fabsf(dtdx); + dtdy = fabsf(dtdy); + max = MAX2(dtdx, dtdy) * tex->height[0]; + rho = MAX2(rho, max); + } + if (p) { + float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]; + float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]; + float max; + dpdx = fabsf(dpdx); + dpdy = fabsf(dpdy); + max = MAX2(dpdx, dpdy) * tex->depth[0]; + rho = MAX2(rho, max); + } + + lambda = util_fast_log2(rho); + lambda += lodbias + sampler->lod_bias; + lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod); + + return lambda; +} + + +/** + * Do several things here: + * 1. Compute lambda from the texcoords, if needed + * 2. Determine if we're minifying or magnifying + * 3. If minifying, choose mipmap levels + * 4. Return image filter to use within mipmap images + * \param level0 Returns first mipmap level to sample from + * \param level1 Returns second mipmap level to sample from + * \param levelBlend Returns blend factor between levels, in [0,1] + * \param imgFilter Returns either the min or mag filter, depending on lambda + */ +static void +choose_mipmap_levels(const struct pipe_texture *texture, + const struct pipe_sampler_state *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + boolean computeLambda, + float lodbias, + unsigned *level0, unsigned *level1, float *levelBlend, + unsigned *imgFilter) +{ + if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { + /* no mipmap selection needed */ + *level0 = *level1 = CLAMP((int) sampler->min_lod, + 0, (int) texture->last_level); + + if (sampler->min_img_filter != sampler->mag_img_filter) { + /* non-mipmapped texture, but still need to determine if doing + * minification or magnification. + */ + float lambda = compute_lambda(texture, sampler, s, t, p, lodbias); + if (lambda <= 0.0) { + *imgFilter = sampler->mag_img_filter; + } + else { + *imgFilter = sampler->min_img_filter; + } + } + else { + *imgFilter = sampler->mag_img_filter; + } + } + else { + float lambda; + + if (computeLambda) + /* fragment shader */ + lambda = compute_lambda(texture, sampler, s, t, p, lodbias); + else + /* vertex shader */ + lambda = lodbias; /* not really a bias, but absolute LOD */ + + if (lambda <= 0.0) { /* XXX threshold depends on the filter */ + /* magnifying */ + *imgFilter = sampler->mag_img_filter; + *level0 = *level1 = 0; + } + else { + /* minifying */ + *imgFilter = sampler->min_img_filter; + + /* choose mipmap level(s) and compute the blend factor between them */ + if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) { + /* Nearest mipmap level */ + const int lvl = (int) (lambda + 0.5); + *level0 = + *level1 = CLAMP(lvl, 0, (int) texture->last_level); + } + else { + /* Linear interpolation between mipmap levels */ + const int lvl = (int) lambda; + *level0 = CLAMP(lvl, 0, (int) texture->last_level); + *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level); + *levelBlend = FRAC(lambda); /* blending weight between levels */ + } + } + } +} + + +/** + * Get a texel from a texture, using the texture tile cache. + * + * \param face the cube face in 0..5 + * \param level the mipmap level + * \param x the x coord of texel within 2D image + * \param y the y coord of texel within 2D image + * \param z which slice of a 3D texture + * \param rgba the quad to put the texel/color into + * \param j which element of the rgba quad to write to + * + * XXX maybe move this into lp_tile_cache.c and merge with the + * lp_get_cached_tile_tex() function. Also, get 4 texels instead of 1... + */ +static void +get_texel(const struct tgsi_sampler *tgsi_sampler, + unsigned face, unsigned level, int x, int y, int z, + float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j) +{ + const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler); + struct llvmpipe_context *lp = samp->lp; + const uint unit = samp->unit; + const struct pipe_texture *texture = lp->texture[unit]; + const struct pipe_sampler_state *sampler = lp->sampler[unit]; + + if (x < 0 || x >= (int) texture->width[level] || + y < 0 || y >= (int) texture->height[level] || + z < 0 || z >= (int) texture->depth[level]) { + rgba[0][j] = sampler->border_color[0]; + rgba[1][j] = sampler->border_color[1]; + rgba[2][j] = sampler->border_color[2]; + rgba[3][j] = sampler->border_color[3]; + } + else { + const int tx = x % TILE_SIZE; + const int ty = y % TILE_SIZE; + const struct llvmpipe_cached_tile *tile + = lp_get_cached_tile_tex(lp, samp->cache, + x, y, z, face, level); + rgba[0][j] = tile->data.color[ty][tx][0]; + rgba[1][j] = tile->data.color[ty][tx][1]; + rgba[2][j] = tile->data.color[ty][tx][2]; + rgba[3][j] = tile->data.color[ty][tx][3]; + if (0) + { + debug_printf("Get texel %f %f %f %f from %s\n", + rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j], + pf_name(texture->format)); + } + } +} + + +/** + * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' + * When we sampled the depth texture, the depth value was put into all + * RGBA channels. We look at the red channel here. + * \param rgba quad of (depth) texel values + * \param p texture 'P' components for four pixels in quad + * \param j which pixel in the quad to test [0..3] + */ +static INLINE void +shadow_compare(const struct pipe_sampler_state *sampler, + float rgba[NUM_CHANNELS][QUAD_SIZE], + const float p[QUAD_SIZE], + uint j) +{ + int k; + switch (sampler->compare_func) { + case PIPE_FUNC_LESS: + k = p[j] < rgba[0][j]; + break; + case PIPE_FUNC_LEQUAL: + k = p[j] <= rgba[0][j]; + break; + case PIPE_FUNC_GREATER: + k = p[j] > rgba[0][j]; + break; + case PIPE_FUNC_GEQUAL: + k = p[j] >= rgba[0][j]; + break; + case PIPE_FUNC_EQUAL: + k = p[j] == rgba[0][j]; + break; + case PIPE_FUNC_NOTEQUAL: + k = p[j] != rgba[0][j]; + break; + case PIPE_FUNC_ALWAYS: + k = 1; + break; + case PIPE_FUNC_NEVER: + k = 0; + break; + default: + k = 0; + assert(0); + break; + } + + /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ + rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; + rgba[3][j] = 1.0F; +} + + +/** + * As above, but do four z/texture comparisons. + */ +static INLINE void +shadow_compare4(const struct pipe_sampler_state *sampler, + float rgba[NUM_CHANNELS][QUAD_SIZE], + const float p[QUAD_SIZE]) +{ + int j, k0, k1, k2, k3; + float val; + + /* compare four texcoords vs. four texture samples */ + switch (sampler->compare_func) { + case PIPE_FUNC_LESS: + k0 = p[0] < rgba[0][0]; + k1 = p[1] < rgba[0][1]; + k2 = p[2] < rgba[0][2]; + k3 = p[3] < rgba[0][3]; + break; + case PIPE_FUNC_LEQUAL: + k0 = p[0] <= rgba[0][0]; + k1 = p[1] <= rgba[0][1]; + k2 = p[2] <= rgba[0][2]; + k3 = p[3] <= rgba[0][3]; + break; + case PIPE_FUNC_GREATER: + k0 = p[0] > rgba[0][0]; + k1 = p[1] > rgba[0][1]; + k2 = p[2] > rgba[0][2]; + k3 = p[3] > rgba[0][3]; + break; + case PIPE_FUNC_GEQUAL: + k0 = p[0] >= rgba[0][0]; + k1 = p[1] >= rgba[0][1]; + k2 = p[2] >= rgba[0][2]; + k3 = p[3] >= rgba[0][3]; + break; + case PIPE_FUNC_EQUAL: + k0 = p[0] == rgba[0][0]; + k1 = p[1] == rgba[0][1]; + k2 = p[2] == rgba[0][2]; + k3 = p[3] == rgba[0][3]; + break; + case PIPE_FUNC_NOTEQUAL: + k0 = p[0] != rgba[0][0]; + k1 = p[1] != rgba[0][1]; + k2 = p[2] != rgba[0][2]; + k3 = p[3] != rgba[0][3]; + break; + case PIPE_FUNC_ALWAYS: + k0 = k1 = k2 = k3 = 1; + break; + case PIPE_FUNC_NEVER: + k0 = k1 = k2 = k3 = 0; + break; + default: + k0 = k1 = k2 = k3 = 0; + assert(0); + break; + } + + /* convert four pass/fail values to an intensity in [0,1] */ + val = 0.25F * (k0 + k1 + k2 + k3); + + /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */ + for (j = 0; j < 4; j++) { + rgba[0][j] = rgba[1][j] = rgba[2][j] = val; + rgba[3][j] = 1.0F; + } +} + + +/** + * Common code for sampling 1D/2D/cube textures. + * Could probably extend for 3D... + */ +static void +lp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + boolean computeLambda, + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE], + const unsigned faces[4]) +{ + const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler); + const struct llvmpipe_context *lp = samp->lp; + const uint unit = samp->unit; + const struct pipe_texture *texture = lp->texture[unit]; + const struct pipe_sampler_state *sampler = lp->sampler[unit]; + unsigned level0, level1, j, imgFilter; + int width, height; + float levelBlend; + + choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, + &level0, &level1, &levelBlend, &imgFilter); + + assert(sampler->normalized_coords); + + width = texture->width[level0]; + height = texture->height[level0]; + + assert(width > 0); + + switch (imgFilter) { + case PIPE_TEX_FILTER_NEAREST: + { + int x[4], y[4]; + nearest_texcoord_4(sampler->wrap_s, s, width, x); + nearest_texcoord_4(sampler->wrap_t, t, height, y); + + for (j = 0; j < QUAD_SIZE; j++) { + get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j); + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare(sampler, rgba, p, j); + } + + if (level0 != level1) { + /* get texels from second mipmap level and blend */ + float rgba2[4][4]; + unsigned c; + x[j] /= 2; + y[j] /= 2; + get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0, + rgba2, j); + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ + shadow_compare(sampler, rgba2, p, j); + } + + for (c = 0; c < NUM_CHANNELS; c++) { + rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); + } + } + } + } + break; + case PIPE_TEX_FILTER_LINEAR: + case PIPE_TEX_FILTER_ANISO: + { + int x0[4], y0[4], x1[4], y1[4]; + float xw[4], yw[4]; /* weights */ + + linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw); + linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw); + + for (j = 0; j < QUAD_SIZE; j++) { + float tx[4][4]; /* texels */ + int c; + get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0); + get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1); + get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2); + get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3); + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare4(sampler, tx, p); + } + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_2d(xw[j], yw[j], + tx[c][0], tx[c][1], + tx[c][2], tx[c][3]); + } + + if (level0 != level1) { + /* get texels from second mipmap level and blend */ + float rgba2[4][4]; + x0[j] /= 2; + y0[j] /= 2; + x1[j] /= 2; + y1[j] /= 2; + get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0); + get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1); + get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2); + get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3); + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){ + shadow_compare4(sampler, tx, p); + } + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba2[c][j] = lerp_2d(xw[j], yw[j], + tx[c][0], tx[c][1], tx[c][2], tx[c][3]); + } + + for (c = 0; c < NUM_CHANNELS; c++) { + rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); + } + } + } + } + break; + default: + assert(0); + } +} + + +static INLINE void +lp_get_samples_1d(const struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + boolean computeLambda, + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + static const unsigned faces[4] = {0, 0, 0, 0}; + static const float tzero[4] = {0, 0, 0, 0}; + lp_get_samples_2d_common(sampler, s, tzero, NULL, + computeLambda, lodbias, rgba, faces); +} + + +static INLINE void +lp_get_samples_2d(const struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + boolean computeLambda, + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + static const unsigned faces[4] = {0, 0, 0, 0}; + lp_get_samples_2d_common(sampler, s, t, p, + computeLambda, lodbias, rgba, faces); +} + + +static INLINE void +lp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + boolean computeLambda, + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler); + const struct llvmpipe_context *lp = samp->lp; + const uint unit = samp->unit; + const struct pipe_texture *texture = lp->texture[unit]; + const struct pipe_sampler_state *sampler = lp->sampler[unit]; + /* get/map pipe_surfaces corresponding to 3D tex slices */ + unsigned level0, level1, j, imgFilter; + int width, height, depth; + float levelBlend; + const uint face = 0; + + choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, + &level0, &level1, &levelBlend, &imgFilter); + + assert(sampler->normalized_coords); + + width = texture->width[level0]; + height = texture->height[level0]; + depth = texture->depth[level0]; + + assert(width > 0); + assert(height > 0); + assert(depth > 0); + + switch (imgFilter) { + case PIPE_TEX_FILTER_NEAREST: + { + int x[4], y[4], z[4]; + nearest_texcoord_4(sampler->wrap_s, s, width, x); + nearest_texcoord_4(sampler->wrap_t, t, height, y); + nearest_texcoord_4(sampler->wrap_r, p, depth, z); + for (j = 0; j < QUAD_SIZE; j++) { + get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j); + if (level0 != level1) { + /* get texels from second mipmap level and blend */ + float rgba2[4][4]; + unsigned c; + x[j] /= 2; + y[j] /= 2; + z[j] /= 2; + get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j); + for (c = 0; c < NUM_CHANNELS; c++) { + rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]); + } + } + } + } + break; + case PIPE_TEX_FILTER_LINEAR: + case PIPE_TEX_FILTER_ANISO: + { + int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; + float xw[4], yw[4], zw[4]; /* interpolation weights */ + linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw); + linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw); + linear_texcoord_4(sampler->wrap_r, p, depth, z0, z1, zw); + + for (j = 0; j < QUAD_SIZE; j++) { + int c; + float tx0[4][4], tx1[4][4]; + get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0); + get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1); + get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2); + get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3); + get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0); + get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1); + get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2); + get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3); + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j], + tx0[c][0], tx0[c][1], + tx0[c][2], tx0[c][3], + tx1[c][0], tx1[c][1], + tx1[c][2], tx1[c][3]); + } + + if (level0 != level1) { + /* get texels from second mipmap level and blend */ + float rgba2[4][4]; + x0[j] /= 2; + y0[j] /= 2; + z0[j] /= 2; + x1[j] /= 2; + y1[j] /= 2; + z1[j] /= 2; + get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0); + get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1); + get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2); + get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3); + get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0); + get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1); + get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2); + get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3); + + /* interpolate R, G, B, A */ + for (c = 0; c < 4; c++) { + rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j], + tx0[c][0], tx0[c][1], + tx0[c][2], tx0[c][3], + tx1[c][0], tx1[c][1], + tx1[c][2], tx1[c][3]); + } + + /* blend mipmap levels */ + for (c = 0; c < NUM_CHANNELS; c++) { + rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]); + } + } + } + } + break; + default: + assert(0); + } +} + + +static void +lp_get_samples_cube(const struct tgsi_sampler *sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + boolean computeLambda, + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + unsigned faces[QUAD_SIZE], j; + float ssss[4], tttt[4]; + for (j = 0; j < QUAD_SIZE; j++) { + faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j); + } + lp_get_samples_2d_common(sampler, ssss, tttt, NULL, + computeLambda, lodbias, rgba, faces); +} + + +static void +lp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + boolean computeLambda, + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler); + const struct llvmpipe_context *lp = samp->lp; + const uint unit = samp->unit; + const struct pipe_texture *texture = lp->texture[unit]; + const struct pipe_sampler_state *sampler = lp->sampler[unit]; + const uint face = 0; + unsigned level0, level1, j, imgFilter; + int width, height; + float levelBlend; + + choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias, + &level0, &level1, &levelBlend, &imgFilter); + + /* texture RECTS cannot be mipmapped */ + assert(level0 == level1); + + width = texture->width[level0]; + height = texture->height[level0]; + + assert(width > 0); + + switch (imgFilter) { + case PIPE_TEX_FILTER_NEAREST: + { + int x[4], y[4]; + nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x); + nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y); + for (j = 0; j < QUAD_SIZE; j++) { + get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j); + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare(sampler, rgba, p, j); + } + } + } + break; + case PIPE_TEX_FILTER_LINEAR: + case PIPE_TEX_FILTER_ANISO: + { + int x0[4], y0[4], x1[4], y1[4]; + float xw[4], yw[4]; /* weights */ + linear_texcoord_unnorm_4(sampler->wrap_s, s, width, x0, x1, xw); + linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw); + for (j = 0; j < QUAD_SIZE; j++) { + float tx[4][4]; /* texels */ + int c; + get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0); + get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1); + get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2); + get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3); + if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + shadow_compare4(sampler, tx, p); + } + for (c = 0; c < 4; c++) { + rgba[c][j] = lerp_2d(xw[j], yw[j], + tx[c][0], tx[c][1], tx[c][2], tx[c][3]); + } + } + } + break; + default: + assert(0); + } +} + + +/** + * Common code for vertex/fragment program texture sampling. + */ +static INLINE void +lp_get_samples(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + boolean computeLambda, + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler); + const struct llvmpipe_context *lp = samp->lp; + const uint unit = samp->unit; + const struct pipe_texture *texture = lp->texture[unit]; + const struct pipe_sampler_state *sampler = lp->sampler[unit]; + + if (!texture) + return; + + switch (texture->target) { + case PIPE_TEXTURE_1D: + assert(sampler->normalized_coords); + lp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + break; + case PIPE_TEXTURE_2D: + if (sampler->normalized_coords) + lp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + else + lp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + break; + case PIPE_TEXTURE_3D: + assert(sampler->normalized_coords); + lp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + break; + case PIPE_TEXTURE_CUBE: + assert(sampler->normalized_coords); + lp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba); + break; + default: + assert(0); + } + +#if 0 /* DEBUG */ + { + int i; + printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]); + for (i = 0; i < 4; i++) { + printf("Frag %d: %f %f %f %f\n", i, + rgba[0][i], + rgba[1][i], + rgba[2][i], + rgba[3][i]); + } + } +#endif +} + + +/** + * Called via tgsi_sampler::get_samples() when running a fragment shader. + * Get four filtered RGBA values from the sampler's texture. + */ +void +lp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + lp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba); +} + + +/** + * Called via tgsi_sampler::get_samples() when running a vertex shader. + * Get four filtered RGBA values from the sampler's texture. + */ +void +lp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]) +{ + lp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba); +} diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h new file mode 100644 index 0000000000..3cf292dcbd --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h @@ -0,0 +1,73 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_TEX_SAMPLE_H +#define SP_TEX_SAMPLE_H + + +#include "tgsi/tgsi_exec.h" + + +/** + * Subclass of tgsi_sampler + */ +struct lp_shader_sampler +{ + struct tgsi_sampler base; /**< base class */ + + uint unit; + struct llvmpipe_context *lp; + struct llvmpipe_tile_cache *cache; +}; + + + +static INLINE const struct lp_shader_sampler * +lp_shader_sampler(const struct tgsi_sampler *sampler) +{ + return (const struct lp_shader_sampler *) sampler; +} + + +extern void +lp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); + +extern void +lp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler, + const float s[QUAD_SIZE], + const float t[QUAD_SIZE], + const float p[QUAD_SIZE], + float lodbias, + float rgba[NUM_CHANNELS][QUAD_SIZE]); + + +#endif /* SP_TEX_SAMPLE_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c new file mode 100644 index 0000000000..fd9b5182ea --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -0,0 +1,421 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/internal/p_winsys_screen.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "lp_context.h" +#include "lp_state.h" +#include "lp_texture.h" +#include "lp_tile_cache.h" +#include "lp_screen.h" +#include "lp_winsys.h" + + +/* Simple, maximally packed layout. + */ + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +/* Conventional allocation path for non-display textures: + */ +static boolean +llvmpipe_texture_layout(struct pipe_screen *screen, + struct llvmpipe_texture * lpt) +{ + struct pipe_texture *pt = &lpt->base; + unsigned level; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + + unsigned buffer_size = 0; + + for (level = 0; level <= pt->last_level; level++) { + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height); + lpt->stride[level] = pt->nblocksx[level]*pt->block.size; + + lpt->level_offset[level] = buffer_size; + + buffer_size += (pt->nblocksy[level] * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + lpt->stride[level]); + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + + lpt->buffer = screen->buffer_create(screen, 32, + PIPE_BUFFER_USAGE_PIXEL, + buffer_size); + + return lpt->buffer != NULL; +} + +static boolean +llvmpipe_displaytarget_layout(struct pipe_screen *screen, + struct llvmpipe_texture * lpt) +{ + unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE | + PIPE_BUFFER_USAGE_GPU_READ_WRITE); + + lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]); + lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]); + + lpt->buffer = screen->surface_buffer_create( screen, + lpt->base.width[0], + lpt->base.height[0], + lpt->base.format, + usage, + &lpt->stride[0]); + + return lpt->buffer != NULL; +} + + + + + +static struct pipe_texture * +llvmpipe_texture_create(struct pipe_screen *screen, + const struct pipe_texture *templat) +{ + struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); + if (!lpt) + return NULL; + + lpt->base = *templat; + pipe_reference_init(&lpt->base.reference, 1); + lpt->base.screen = screen; + + if (lpt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!llvmpipe_displaytarget_layout(screen, lpt)) + goto fail; + } + else { + if (!llvmpipe_texture_layout(screen, lpt)) + goto fail; + } + + return &lpt->base; + + fail: + FREE(lpt); + return NULL; +} + + +static struct pipe_texture * +llvmpipe_texture_blanket(struct pipe_screen * screen, + const struct pipe_texture *base, + const unsigned *stride, + struct pipe_buffer *buffer) +{ + struct llvmpipe_texture *lpt; + assert(screen); + + /* Only supports one type */ + if (base->target != PIPE_TEXTURE_2D || + base->last_level != 0 || + base->depth[0] != 1) { + return NULL; + } + + lpt = CALLOC_STRUCT(llvmpipe_texture); + if (!lpt) + return NULL; + + lpt->base = *base; + pipe_reference_init(&lpt->base.reference, 1); + lpt->base.screen = screen; + lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]); + lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]); + lpt->stride[0] = stride[0]; + + pipe_buffer_reference(&lpt->buffer, buffer); + + return &lpt->base; +} + + +static void +llvmpipe_texture_destroy(struct pipe_texture *pt) +{ + struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + + pipe_buffer_reference(&lpt->buffer, NULL); + FREE(lpt); +} + + +static struct pipe_surface * +llvmpipe_get_tex_surface(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned usage) +{ + struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + struct pipe_surface *ps; + + assert(level <= pt->last_level); + + ps = CALLOC_STRUCT(pipe_surface); + if (ps) { + pipe_reference_init(&ps->reference, 1); + pipe_texture_reference(&ps->texture, pt); + ps->format = pt->format; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->offset = lpt->level_offset[level]; + ps->usage = usage; + + /* Because we are llvmpipe, anything that the state tracker + * thought was going to be done with the GPU will actually get + * done with the CPU. Let's adjust the flags to take that into + * account. + */ + if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) { + /* GPU_WRITE means "render" and that can involve reads (blending) */ + ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ; + } + + if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) + ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; + + if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_WRITE)) { + /* Mark the surface as dirty. The tile cache will look for this. */ + lpt->modified = TRUE; + } + + ps->face = face; + ps->level = level; + ps->zslice = zslice; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset += face * pt->nblocksy[level] * lpt->stride[level]; + } + else if (pt->target == PIPE_TEXTURE_3D) { + ps->offset += zslice * pt->nblocksy[level] * lpt->stride[level]; + } + else { + assert(face == 0); + assert(zslice == 0); + } + } + return ps; +} + + +static void +llvmpipe_tex_surface_destroy(struct pipe_surface *surf) +{ + /* Effectively do the texture_update work here - if texture images + * needed post-processing to put them into hardware layout, this is + * where it would happen. For llvmpipe, nothing to do. + */ + assert(surf->texture); + pipe_texture_reference(&surf->texture, NULL); + FREE(surf); +} + + +static struct pipe_transfer * +llvmpipe_get_tex_transfer(struct pipe_screen *screen, + struct pipe_texture *texture, + unsigned face, unsigned level, unsigned zslice, + enum pipe_transfer_usage usage, + unsigned x, unsigned y, unsigned w, unsigned h) +{ + struct llvmpipe_texture *lptex = llvmpipe_texture(texture); + struct llvmpipe_transfer *lpt; + + assert(texture); + assert(level <= texture->last_level); + + lpt = CALLOC_STRUCT(llvmpipe_transfer); + if (lpt) { + struct pipe_transfer *pt = &lpt->base; + pipe_texture_reference(&pt->texture, texture); + pt->format = texture->format; + pt->block = texture->block; + pt->x = x; + pt->y = y; + pt->width = w; + pt->height = h; + pt->nblocksx = texture->nblocksx[level]; + pt->nblocksy = texture->nblocksy[level]; + pt->stride = lptex->stride[level]; + pt->usage = usage; + pt->face = face; + pt->level = level; + pt->zslice = zslice; + + lpt->offset = lptex->level_offset[level]; + + if (texture->target == PIPE_TEXTURE_CUBE) { + lpt->offset += face * pt->nblocksy * pt->stride; + } + else if (texture->target == PIPE_TEXTURE_3D) { + lpt->offset += zslice * pt->nblocksy * pt->stride; + } + else { + assert(face == 0); + assert(zslice == 0); + } + return pt; + } + return NULL; +} + + +static void +llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer) +{ + /* Effectively do the texture_update work here - if texture images + * needed post-processing to put them into hardware layout, this is + * where it would happen. For llvmpipe, nothing to do. + */ + assert (transfer->texture); + pipe_texture_reference(&transfer->texture, NULL); + FREE(transfer); +} + + +static void * +llvmpipe_transfer_map( struct pipe_screen *screen, + struct pipe_transfer *transfer ) +{ + ubyte *map, *xfer_map; + struct llvmpipe_texture *lpt; + unsigned flags = 0; + + assert(transfer->texture); + lpt = llvmpipe_texture(transfer->texture); + + if (transfer->usage != PIPE_TRANSFER_READ) { + flags |= PIPE_BUFFER_USAGE_CPU_WRITE; + } + + if (transfer->usage != PIPE_TRANSFER_WRITE) { + flags |= PIPE_BUFFER_USAGE_CPU_READ; + } + + map = pipe_buffer_map(screen, lpt->buffer, flags); + if (map == NULL) + return NULL; + + /* May want to different things here depending on read/write nature + * of the map: + */ + if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ) + { + /* Do something to notify sharing contexts of a texture change. + * In llvmpipe, that would mean flushing the texture cache. + */ + llvmpipe_screen(screen)->timestamp++; + } + + xfer_map = map + llvmpipe_transfer(transfer)->offset + + transfer->y / transfer->block.height * transfer->stride + + transfer->x / transfer->block.width * transfer->block.size; + /*printf("map = %p xfer map = %p\n", map, xfer_map);*/ + return xfer_map; +} + + +static void +llvmpipe_transfer_unmap(struct pipe_screen *screen, + struct pipe_transfer *transfer) +{ + struct llvmpipe_texture *lpt; + + assert(transfer->texture); + lpt = llvmpipe_texture(transfer->texture); + + pipe_buffer_unmap( screen, lpt->buffer ); +} + + +void +llvmpipe_init_texture_funcs(struct llvmpipe_context *lp) +{ +} + + +void +llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) +{ + screen->texture_create = llvmpipe_texture_create; + screen->texture_blanket = llvmpipe_texture_blanket; + screen->texture_destroy = llvmpipe_texture_destroy; + + screen->get_tex_surface = llvmpipe_get_tex_surface; + screen->tex_surface_destroy = llvmpipe_tex_surface_destroy; + + screen->get_tex_transfer = llvmpipe_get_tex_transfer; + screen->tex_transfer_destroy = llvmpipe_tex_transfer_destroy; + screen->transfer_map = llvmpipe_transfer_map; + screen->transfer_unmap = llvmpipe_transfer_unmap; +} + + +boolean +llvmpipe_get_texture_buffer( struct pipe_texture *texture, + struct pipe_buffer **buf, + unsigned *stride ) +{ + struct llvmpipe_texture *tex = (struct llvmpipe_texture *)texture; + + if (!tex) + return FALSE; + + pipe_buffer_reference(buf, tex->buffer); + + if (stride) + *stride = tex->stride[0]; + + return TRUE; +} diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h new file mode 100644 index 0000000000..23b37c61c7 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_TEXTURE_H +#define SP_TEXTURE_H + + +#include "pipe/p_state.h" + + +struct pipe_context; +struct pipe_screen; +struct llvmpipe_context; + + +struct llvmpipe_texture +{ + struct pipe_texture base; + + unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + unsigned stride[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; + + boolean modified; +}; + +struct llvmpipe_transfer +{ + struct pipe_transfer base; + + unsigned long offset; +}; + + +/** cast wrappers */ +static INLINE struct llvmpipe_texture * +llvmpipe_texture(struct pipe_texture *pt) +{ + return (struct llvmpipe_texture *) pt; +} + +static INLINE struct llvmpipe_transfer * +llvmpipe_transfer(struct pipe_transfer *pt) +{ + return (struct llvmpipe_transfer *) pt; +} + + +extern void +llvmpipe_init_texture_funcs( struct llvmpipe_context *llvmpipe ); + +extern void +llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen); + + +#endif /* SP_TEXTURE */ diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c new file mode 100644 index 0000000000..870fa8a381 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c @@ -0,0 +1,626 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Texture tile caching. + * + * Author: + * Brian Paul + */ + +#include "pipe/p_inlines.h" +#include "util/u_memory.h" +#include "util/u_tile.h" +#include "lp_context.h" +#include "lp_surface.h" +#include "lp_texture.h" +#include "lp_tile_cache.h" + +#define NUM_ENTRIES 50 + + +/** XXX move these */ +#define MAX_WIDTH 2048 +#define MAX_HEIGHT 2048 + + +struct llvmpipe_tile_cache +{ + struct pipe_screen *screen; + struct pipe_surface *surface; /**< the surface we're caching */ + struct pipe_transfer *transfer; + void *transfer_map; + struct pipe_texture *texture; /**< if caching a texture */ + struct llvmpipe_cached_tile entries[NUM_ENTRIES]; + uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; + float clear_color[4]; /**< for color bufs */ + uint clear_val; /**< for z+stencil, or packed color clear value */ + boolean depth_stencil; /**< Is the surface a depth/stencil format? */ + + struct pipe_transfer *tex_trans; + void *tex_trans_map; + int tex_face, tex_level, tex_z; + + struct llvmpipe_cached_tile tile; /**< scratch tile for clears */ +}; + + +/** + * Return the position in the cache for the tile that contains win pos (x,y). + * We currently use a direct mapped cache so this is like a hack key. + * At some point we should investige something more sophisticated, like + * a LRU replacement policy. + */ +#define CACHE_POS(x, y) \ + (((x) / TILE_SIZE + ((y) / TILE_SIZE) * 5) % NUM_ENTRIES) + + + +/** + * Is the tile at (x,y) in cleared state? + */ +static INLINE uint +is_clear_flag_set(const uint *bitvec, int x, int y) +{ + int pos, bit; + x /= TILE_SIZE; + y /= TILE_SIZE; + pos = y * (MAX_WIDTH / TILE_SIZE) + x; + assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32); + bit = bitvec[pos / 32] & (1 << (pos & 31)); + return bit; +} + + +/** + * Mark the tile at (x,y) as not cleared. + */ +static INLINE void +clear_clear_flag(uint *bitvec, int x, int y) +{ + int pos; + x /= TILE_SIZE; + y /= TILE_SIZE; + pos = y * (MAX_WIDTH / TILE_SIZE) + x; + assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32); + bitvec[pos / 32] &= ~(1 << (pos & 31)); +} + + +struct llvmpipe_tile_cache * +lp_create_tile_cache( struct pipe_screen *screen ) +{ + struct llvmpipe_tile_cache *tc; + uint pos; + + tc = CALLOC_STRUCT( llvmpipe_tile_cache ); + if (tc) { + tc->screen = screen; + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].x = + tc->entries[pos].y = -1; + } + } + return tc; +} + + +void +lp_destroy_tile_cache(struct llvmpipe_tile_cache *tc) +{ + struct pipe_screen *screen; + uint pos; + + for (pos = 0; pos < NUM_ENTRIES; pos++) { + /*assert(tc->entries[pos].x < 0);*/ + } + if (tc->transfer) { + screen = tc->transfer->texture->screen; + screen->tex_transfer_destroy(tc->transfer); + } + if (tc->tex_trans) { + screen = tc->tex_trans->texture->screen; + screen->tex_transfer_destroy(tc->tex_trans); + } + + FREE( tc ); +} + + +/** + * Specify the surface to cache. + */ +void +lp_tile_cache_set_surface(struct llvmpipe_tile_cache *tc, + struct pipe_surface *ps) +{ + assert(!tc->texture); + + if (tc->transfer) { + struct pipe_screen *screen = tc->transfer->texture->screen; + + if (ps == tc->surface) + return; + + if (tc->transfer_map) { + screen->transfer_unmap(screen, tc->transfer); + tc->transfer_map = NULL; + } + + screen->tex_transfer_destroy(tc->transfer); + tc->transfer = NULL; + } + + tc->surface = ps; + + if (ps) { + struct pipe_screen *screen = ps->texture->screen; + + tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face, + ps->level, ps->zslice, + PIPE_TRANSFER_READ_WRITE, + 0, 0, ps->width, ps->height); + + tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || + ps->format == PIPE_FORMAT_X8Z24_UNORM || + ps->format == PIPE_FORMAT_Z24S8_UNORM || + ps->format == PIPE_FORMAT_Z24X8_UNORM || + ps->format == PIPE_FORMAT_Z16_UNORM || + ps->format == PIPE_FORMAT_Z32_UNORM || + ps->format == PIPE_FORMAT_S8_UNORM); + } +} + + +/** + * Return the transfer being cached. + */ +struct pipe_surface * +lp_tile_cache_get_surface(struct llvmpipe_tile_cache *tc) +{ + return tc->surface; +} + + +void +lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc) +{ + if (tc->transfer && !tc->transfer_map) + tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer); + + if (tc->tex_trans && !tc->tex_trans_map) + tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans); +} + + +void +lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc) +{ + if (tc->transfer_map) { + tc->screen->transfer_unmap(tc->screen, tc->transfer); + tc->transfer_map = NULL; + } + + if (tc->tex_trans_map) { + tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } +} + + +/** + * Specify the texture to cache. + */ +void +lp_tile_cache_set_texture(struct pipe_context *pipe, + struct llvmpipe_tile_cache *tc, + struct pipe_texture *texture) +{ + uint i; + + assert(!tc->transfer); + + pipe_texture_reference(&tc->texture, texture); + + if (tc->tex_trans) { + struct pipe_screen *screen = tc->tex_trans->texture->screen; + + if (tc->tex_trans_map) { + screen->transfer_unmap(screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } + + screen->tex_transfer_destroy(tc->tex_trans); + tc->tex_trans = NULL; + } + + /* mark as entries as invalid/empty */ + /* XXX we should try to avoid this when the teximage hasn't changed */ + for (i = 0; i < NUM_ENTRIES; i++) { + tc->entries[i].x = -1; + } + + tc->tex_face = -1; /* any invalid value here */ +} + + +/** + * Set pixels in a tile to the given clear color/value, float. + */ +static void +clear_tile_rgba(struct llvmpipe_cached_tile *tile, + enum pipe_format format, + const float clear_value[4]) +{ + if (clear_value[0] == 0.0 && + clear_value[1] == 0.0 && + clear_value[2] == 0.0 && + clear_value[3] == 0.0) { + memset(tile->data.color, 0, sizeof(tile->data.color)); + } + else { + uint i, j; + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.color[i][j][0] = clear_value[0]; + tile->data.color[i][j][1] = clear_value[1]; + tile->data.color[i][j][2] = clear_value[2]; + tile->data.color[i][j][3] = clear_value[3]; + } + } + } +} + + +/** + * Set a tile to a solid value/color. + */ +static void +clear_tile(struct llvmpipe_cached_tile *tile, + enum pipe_format format, + uint clear_value) +{ + uint i, j; + + switch (pf_get_size(format)) { + case 1: + memset(tile->data.any, 0, TILE_SIZE * TILE_SIZE); + break; + case 2: + if (clear_value == 0) { + memset(tile->data.any, 0, 2 * TILE_SIZE * TILE_SIZE); + } + else { + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.depth16[i][j] = (ushort) clear_value; + } + } + } + break; + case 4: + if (clear_value == 0) { + memset(tile->data.any, 0, 4 * TILE_SIZE * TILE_SIZE); + } + else { + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.color32[i][j] = clear_value; + } + } + } + break; + default: + assert(0); + } +} + + +/** + * Actually clear the tiles which were flagged as being in a clear state. + */ +static void +lp_tile_cache_flush_clear(struct pipe_context *pipe, + struct llvmpipe_tile_cache *tc) +{ + struct pipe_transfer *pt = tc->transfer; + const uint w = tc->transfer->width; + const uint h = tc->transfer->height; + uint x, y; + uint numCleared = 0; + + /* clear the scratch tile to the clear value */ + clear_tile(&tc->tile, pt->format, tc->clear_val); + + /* push the tile to all positions marked as clear */ + for (y = 0; y < h; y += TILE_SIZE) { + for (x = 0; x < w; x += TILE_SIZE) { + if (is_clear_flag_set(tc->clear_flags, x, y)) { + pipe_put_tile_raw(pt, + x, y, TILE_SIZE, TILE_SIZE, + tc->tile.data.color32, 0/*STRIDE*/); + + /* do this? */ + clear_clear_flag(tc->clear_flags, x, y); + + numCleared++; + } + } + } +#if 0 + debug_printf("num cleared: %u\n", numCleared); +#endif +} + + +/** + * Flush the tile cache: write all dirty tiles back to the transfer. + * any tiles "flagged" as cleared will be "really" cleared. + */ +void +lp_flush_tile_cache(struct llvmpipe_context *llvmpipe, + struct llvmpipe_tile_cache *tc) +{ + struct pipe_transfer *pt = tc->transfer; + int inuse = 0, pos; + + if (pt) { + /* caching a drawing transfer */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + struct llvmpipe_cached_tile *tile = tc->entries + pos; + if (tile->x >= 0) { + if (tc->depth_stencil) { + pipe_put_tile_raw(pt, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); + } + else { + pipe_put_tile_rgba(pt, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + } + tile->x = tile->y = -1; /* mark as empty */ + inuse++; + } + } + +#if TILE_CLEAR_OPTIMIZATION + lp_tile_cache_flush_clear(&llvmpipe->pipe, tc); +#endif + } + else if (tc->texture) { + /* caching a texture, mark all entries as empty */ + for (pos = 0; pos < NUM_ENTRIES; pos++) { + tc->entries[pos].x = -1; + } + tc->tex_face = -1; + } + +#if 0 + debug_printf("flushed tiles in use: %d\n", inuse); +#endif +} + + +/** + * Get a tile from the cache. + * \param x, y position of tile, in pixels + */ +struct llvmpipe_cached_tile * +lp_get_cached_tile(struct llvmpipe_context *llvmpipe, + struct llvmpipe_tile_cache *tc, int x, int y) +{ + struct pipe_transfer *pt = tc->transfer; + + /* tile pos in framebuffer: */ + const int tile_x = x & ~(TILE_SIZE - 1); + const int tile_y = y & ~(TILE_SIZE - 1); + + /* cache pos/entry: */ + const int pos = CACHE_POS(x, y); + struct llvmpipe_cached_tile *tile = tc->entries + pos; + + if (tile_x != tile->x || + tile_y != tile->y) { + + if (tile->x != -1) { + /* put dirty tile back in framebuffer */ + if (tc->depth_stencil) { + pipe_put_tile_raw(pt, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); + } + else { + pipe_put_tile_rgba(pt, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + } + } + + tile->x = tile_x; + tile->y = tile_y; + + if (is_clear_flag_set(tc->clear_flags, x, y)) { + /* don't get tile from framebuffer, just clear it */ + if (tc->depth_stencil) { + clear_tile(tile, pt->format, tc->clear_val); + } + else { + clear_tile_rgba(tile, pt->format, tc->clear_color); + } + clear_clear_flag(tc->clear_flags, x, y); + } + else { + /* get new tile data from transfer */ + if (tc->depth_stencil) { + pipe_get_tile_raw(pt, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + tile->data.depth32, 0/*STRIDE*/); + } + else { + pipe_get_tile_rgba(pt, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + } + } + } + + return tile; +} + + +/** + * Given the texture face, level, zslice, x and y values, compute + * the cache entry position/index where we'd hope to find the + * cached texture tile. + * This is basically a direct-map cache. + * XXX There's probably lots of ways in which we can improve this. + */ +static INLINE uint +tex_cache_pos(int x, int y, int z, int face, int level) +{ + uint entry = x + y * 9 + z * 3 + face + level * 7; + return entry % NUM_ENTRIES; +} + + +/** + * Similar to lp_get_cached_tile() but for textures. + * Tiles are read-only and indexed with more params. + */ +const struct llvmpipe_cached_tile * +lp_get_cached_tile_tex(struct llvmpipe_context *lp, + struct llvmpipe_tile_cache *tc, int x, int y, int z, + int face, int level) +{ + struct pipe_screen *screen = lp->pipe.screen; + /* tile pos in framebuffer: */ + const int tile_x = x & ~(TILE_SIZE - 1); + const int tile_y = y & ~(TILE_SIZE - 1); + /* cache pos/entry: */ + const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z, + face, level); + struct llvmpipe_cached_tile *tile = tc->entries + pos; + + if (tc->texture) { + struct llvmpipe_texture *lpt = llvmpipe_texture(tc->texture); + if (lpt->modified) { + /* texture was modified, invalidate all cached tiles */ + uint p; + for (p = 0; p < NUM_ENTRIES; p++) { + tile = tc->entries + p; + tile->x = -1; + } + lpt->modified = FALSE; + } + } + + if (tile_x != tile->x || + tile_y != tile->y || + z != tile->z || + face != tile->face || + level != tile->level) { + /* cache miss */ + +#if 0 + printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos, + x/TILE_SIZE, y/TILE_SIZE, z, face, level); +#endif + /* check if we need to get a new transfer */ + if (!tc->tex_trans || + tc->tex_face != face || + tc->tex_level != level || + tc->tex_z != z) { + /* get new transfer (view into texture) */ + + if (tc->tex_trans) { + if (tc->tex_trans_map) { + tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->tex_trans_map = NULL; + } + + screen->tex_transfer_destroy(tc->tex_trans); + tc->tex_trans = NULL; + } + + tc->tex_trans = screen->get_tex_transfer(screen, tc->texture, face, level, z, + PIPE_TRANSFER_READ, 0, 0, + tc->texture->width[level], + tc->texture->height[level]); + tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); + + tc->tex_face = face; + tc->tex_level = level; + tc->tex_z = z; + } + + /* get tile from the transfer (view into texture) */ + pipe_get_tile_rgba(tc->tex_trans, + tile_x, tile_y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); + tile->x = tile_x; + tile->y = tile_y; + tile->z = z; + tile->face = face; + tile->level = level; + } + + return tile; +} + + +/** + * When a whole surface is being cleared to a value we can avoid + * fetching tiles above. + * Save the color and set a 'clearflag' for each tile of the screen. + */ +void +lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba, + uint clearValue) +{ + uint pos; + + tc->clear_color[0] = rgba[0]; + tc->clear_color[1] = rgba[1]; + tc->clear_color[2] = rgba[2]; + tc->clear_color[3] = rgba[3]; + + tc->clear_val = clearValue; + +#if TILE_CLEAR_OPTIMIZATION + /* set flags to indicate all the tiles are cleared */ + memset(tc->clear_flags, 255, sizeof(tc->clear_flags)); +#else + /* disable the optimization */ + memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); +#endif + + for (pos = 0; pos < NUM_ENTRIES; pos++) { + struct llvmpipe_cached_tile *tile = tc->entries + pos; + tile->x = tile->y = -1; + } +} diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.h b/src/gallium/drivers/llvmpipe/lp_tile_cache.h new file mode 100644 index 0000000000..ac3b17cce3 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.h @@ -0,0 +1,106 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef SP_TILE_CACHE_H +#define SP_TILE_CACHE_H + +#define TILE_CLEAR_OPTIMIZATION 1 + + +#include "pipe/p_compiler.h" + + +struct llvmpipe_context; +struct llvmpipe_tile_cache; + + +/** + * Cache tile size (width and height). This needs to be a power of two. + */ +#define TILE_SIZE 64 + + + +struct llvmpipe_cached_tile +{ + int x, y; /**< pos of tile in window coords */ + int z, face, level; /**< Extra texture indexes */ + union { + float color[TILE_SIZE][TILE_SIZE][4]; + uint color32[TILE_SIZE][TILE_SIZE]; + uint depth32[TILE_SIZE][TILE_SIZE]; + ushort depth16[TILE_SIZE][TILE_SIZE]; + ubyte stencil8[TILE_SIZE][TILE_SIZE]; + ubyte any[1]; + } data; +}; + + +extern struct llvmpipe_tile_cache * +lp_create_tile_cache( struct pipe_screen *screen ); + +extern void +lp_destroy_tile_cache(struct llvmpipe_tile_cache *tc); + +extern void +lp_tile_cache_set_surface(struct llvmpipe_tile_cache *tc, + struct pipe_surface *lps); + +extern struct pipe_surface * +lp_tile_cache_get_surface(struct llvmpipe_tile_cache *tc); + +extern void +lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc); + +extern void +lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc); + +extern void +lp_tile_cache_set_texture(struct pipe_context *pipe, + struct llvmpipe_tile_cache *tc, + struct pipe_texture *texture); + +extern void +lp_flush_tile_cache(struct llvmpipe_context *llvmpipe, + struct llvmpipe_tile_cache *tc); + +extern void +lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba, + uint clearValue); + +extern struct llvmpipe_cached_tile * +lp_get_cached_tile(struct llvmpipe_context *llvmpipe, + struct llvmpipe_tile_cache *tc, int x, int y); + +extern const struct llvmpipe_cached_tile * +lp_get_cached_tile_tex(struct llvmpipe_context *llvmpipe, + struct llvmpipe_tile_cache *tc, int x, int y, int z, + int face, int level); + + +#endif /* SP_TILE_CACHE_H */ + diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/drivers/llvmpipe/lp_winsys.h new file mode 100644 index 0000000000..ec371c00db --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_winsys.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* This is the interface that llvmpipe requires any window system + * hosting it to implement. This is the only include file in llvmpipe + * which is public. + */ + + +#ifndef SP_WINSYS_H +#define SP_WINSYS_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct pipe_screen; +struct pipe_winsys; +struct pipe_context; + + +struct pipe_context *llvmpipe_create( struct pipe_screen * ); + + +struct pipe_screen * +llvmpipe_create_screen(struct pipe_winsys *); + + +boolean +llvmpipe_get_texture_buffer( struct pipe_texture *texture, + struct pipe_buffer **buf, + unsigned *stride ); + + +#ifdef __cplusplus +} +#endif + +#endif /* SP_WINSYS_H */ -- cgit v1.2.3