From 20f087863d00fed9823791a447932e74d77cc546 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 8 Jun 2011 11:25:04 -0700 Subject: glsl: Fix incorrect optimization of instructions before discard statements. The function was named "find_unconditional_discard", but didn't actually check that the discard statement found was unconditional. Fixes piglit glsl-fs-discard-04. Reviewed-by: Kenneth Graunke --- src/glsl/opt_discard_simplification.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/opt_discard_simplification.cpp b/src/glsl/opt_discard_simplification.cpp index 7c2928d271c..a19947ddd6c 100644 --- a/src/glsl/opt_discard_simplification.cpp +++ b/src/glsl/opt_discard_simplification.cpp @@ -104,9 +104,23 @@ static ir_discard * find_unconditional_discard(exec_list &instructions) { foreach_list(n, &instructions) { - ir_discard *ir = ((ir_instruction *) n)->as_discard(); - if (ir != NULL && ir->condition == NULL) - return ir; + ir_instruction *ir = (ir_instruction *)n; + + if (ir->ir_type == ir_type_return || + ir->ir_type == ir_type_loop_jump) + return NULL; + + /* So far, this code doesn't know how to look inside of flow + * control to see if a discard later on at this level is + * unconditional. + */ + if (ir->ir_type == ir_type_if || + ir->ir_type == ir_type_loop) + return NULL; + + ir_discard *discard = ir->as_discard(); + if (discard != NULL && discard->condition == NULL) + return discard; } return NULL; } -- cgit v1.2.3 From 7c7a8a38e530a63717a2f374ae0574d8abf11e17 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 13 Jun 2011 17:43:32 -0700 Subject: glsl/generate_builtins.py: Remove regexp to kill pointer addresses. Commit 56ef62d9885f805bbfb2243dc860ff425d5b4d3b "glsl: Generate readable unique names at print time." changed ir_print_visitor to not generate @0x1234567 suffixes except where necessary. So there's no need to manually remove them. Signed-off-by: Kenneth Graunke --- src/glsl/builtins/tools/generate_builtins.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/builtins/tools/generate_builtins.py b/src/glsl/builtins/tools/generate_builtins.py index edd3c70e00b..17d528c2180 100755 --- a/src/glsl/builtins/tools/generate_builtins.py +++ b/src/glsl/builtins/tools/generate_builtins.py @@ -82,10 +82,6 @@ def write_profile(filename, profile): kill_globals = re.compile(r'^\(declare.*\n', re.MULTILINE) proto_ir = kill_globals.sub('', proto_ir) - # Kill pointer addresses. They're not necessary in prototypes and just - # clutter the diff output. - proto_ir = re.sub(r'@0x[0-9a-f]+', '', proto_ir) - print 'static const char prototypes_for_' + profile + '[] =' print stringify(proto_ir), ';' -- cgit v1.2.3 From ef8f6a8c59e88fb7498f3a0f7440bcc4ec1e8a98 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 14 Jun 2011 21:36:43 -0700 Subject: glsl/builtins: Actually implement int/ivec variants of abs(). Signed-off-by: Kenneth Graunke NOTE: This is a candidate for stable release branches (and don't forget to re-run "make builtins" after cherry-picking.) --- src/glsl/builtins/ir/abs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/glsl') diff --git a/src/glsl/builtins/ir/abs b/src/glsl/builtins/ir/abs index 904845307c4..d07d1d99e9f 100644 --- a/src/glsl/builtins/ir/abs +++ b/src/glsl/builtins/ir/abs @@ -18,4 +18,24 @@ (parameters (declare (in) vec4 arg0)) ((return (expression vec4 abs (var_ref arg0))))) + + (signature int + (parameters + (declare (in) int arg0)) + ((return (expression int abs (var_ref arg0))))) + + (signature ivec2 + (parameters + (declare (in) ivec2 arg0)) + ((return (expression ivec2 abs (var_ref arg0))))) + + (signature ivec3 + (parameters + (declare (in) ivec3 arg0)) + ((return (expression ivec3 abs (var_ref arg0))))) + + (signature ivec4 + (parameters + (declare (in) ivec4 arg0)) + ((return (expression ivec4 abs (var_ref arg0))))) )) -- cgit v1.2.3 From 41750107496858a047afa8d81d20fe903f285a78 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 17 Jun 2011 14:48:28 +0100 Subject: scons: make embedding orthogonal to the platform To enable embedding in platforms other than linux. --- SConstruct | 19 +------- common.py | 3 +- scons/gallium.py | 6 ++- src/gallium/SConscript | 74 ++++++++++++++++---------------- src/gallium/auxiliary/os/os_memory.h | 2 +- src/gallium/auxiliary/os/os_misc.h | 4 -- src/gallium/auxiliary/os/os_thread.h | 12 +++--- src/gallium/auxiliary/os/os_time.c | 5 --- src/gallium/auxiliary/util/u_debug.c | 2 +- src/gallium/drivers/llvmpipe/SConscript | 2 +- src/gallium/drivers/llvmpipe/lp_screen.c | 2 +- src/gallium/include/pipe/p_config.h | 4 -- src/glsl/SConscript | 4 +- 13 files changed, 56 insertions(+), 83 deletions(-) (limited to 'src/glsl') diff --git a/SConstruct b/SConstruct index 8607d2cd8e0..dc5fd776a71 100644 --- a/SConstruct +++ b/SConstruct @@ -80,23 +80,6 @@ env.Append(CPPPATH = [ if env['msvc']: env.Append(CPPPATH = ['#include/c99']) -# Embedded -if env['platform'] == 'embedded': - env.Append(CPPDEFINES = [ - '_POSIX_SOURCE', - ('_POSIX_C_SOURCE', '199309L'), - '_SVID_SOURCE', - '_BSD_SOURCE', - '_GNU_SOURCE', - - 'PTHREADS', - ]) - env.Append(LIBS = [ - 'm', - 'pthread', - 'dl', - ]) - # Posix if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'): env.Append(CPPDEFINES = [ @@ -130,7 +113,7 @@ if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'): # # Create host environent -if env['crosscompile'] and env['platform'] != 'embedded': +if env['crosscompile'] and not env['embedded']: host_env = Environment( options = opts, # no tool used diff --git a/common.py b/common.py index 0a3dcdcf543..052929e2bb0 100644 --- a/common.py +++ b/common.py @@ -83,7 +83,8 @@ def AddOptions(opts): opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, allowed_values=('generic', 'ppc', 'x86', 'x86_64'))) opts.Add(EnumOption('platform', 'target platform', host_platform, - allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'embedded', 'cygwin', 'sunos', 'freebsd8'))) + allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'cygwin', 'sunos', 'freebsd8'))) + opts.Add(BoolOption('embedded', 'embedded build', 'no')) opts.Add('toolchain', 'compiler toolchain', default_toolchain) opts.Add(BoolOption('gles', 'EXPERIMENTAL: enable OpenGL ES support', 'no')) opts.Add(BoolOption('llvm', 'use LLVM', default_llvm)) diff --git a/scons/gallium.py b/scons/gallium.py index a94bf736480..57acfe032f2 100755 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -247,6 +247,8 @@ def generate(env): # configuration. See also http://www.scons.org/wiki/AdvancedBuildExample build_topdir = 'build' build_subdir = env['platform'] + if env['embedded']: + build_subdir = 'embedded-' + build_subdir if env['machine'] != 'generic': build_subdir += '-' + env['machine'] if env['build'] != 'release': @@ -349,8 +351,8 @@ def generate(env): if platform == 'wince': cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE'] cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE_OGL'] - if platform == 'embedded': - cppdefines += ['PIPE_OS_EMBEDDED'] + if env['embedded']: + cppdefines += ['PIPE_SUBSYSTEM_EMBEDDED'] env.Append(CPPDEFINES = cppdefines) # C compiler options diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 428bc31f86b..3072ee936f2 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -53,7 +53,7 @@ if env['drm']: # Needed by some state trackers SConscript('winsys/sw/null/SConscript') -if env['platform'] != 'embedded': +if not env['embedded']: SConscript('state_trackers/vega/SConscript') SConscript('state_trackers/egl/SConscript') @@ -66,8 +66,8 @@ if env['platform'] != 'embedded': if env['dri'] and env['xorg']: SConscript('state_trackers/xorg/SConscript') -if env['platform'] == 'windows': - SConscript('state_trackers/wgl/SConscript') + if env['platform'] == 'windows': + SConscript('state_trackers/wgl/SConscript') # # Winsys @@ -83,55 +83,55 @@ SConscript([ 'targets/graw-null/SConscript', ]) -if env['platform'] != 'embedded': +if not env['embedded']: SConscript([ 'targets/egl-static/SConscript' ]) -if env['x11']: - SConscript([ - 'targets/graw-xlib/SConscript', - 'targets/libgl-xlib/SConscript', - ]) + if env['x11']: + SConscript([ + 'targets/graw-xlib/SConscript', + 'targets/libgl-xlib/SConscript', + ]) -if env['platform'] == 'windows': - SConscript([ - 'targets/graw-gdi/SConscript', - 'targets/libgl-gdi/SConscript', - ]) + if env['platform'] == 'windows': + SConscript([ + 'targets/graw-gdi/SConscript', + 'targets/libgl-gdi/SConscript', + ]) -if env['dri']: - SConscript([ - 'targets/SConscript.dri', - 'targets/dri-swrast/SConscript', - 'targets/dri-vmwgfx/SConscript', - #'targets/dri-nouveau/SConscript', - ]) - if env['drm_intel']: + if env['dri']: SConscript([ - 'targets/dri-i915/SConscript', - 'targets/dri-i965/SConscript', + 'targets/SConscript.dri', + 'targets/dri-swrast/SConscript', + 'targets/dri-vmwgfx/SConscript', + #'targets/dri-nouveau/SConscript', ]) - if env['drm_radeon']: + if env['drm_intel']: + SConscript([ + 'targets/dri-i915/SConscript', + 'targets/dri-i965/SConscript', + ]) + if env['drm_radeon']: + SConscript([ + 'targets/dri-r300/SConscript', + 'targets/dri-r600/SConscript', + ]) + + if env['xorg'] and env['drm']: SConscript([ - 'targets/dri-r300/SConscript', - 'targets/dri-r600/SConscript', + #'targets/xorg-i915/SConscript', + #'targets/xorg-i965/SConscript', + #'targets/xorg-nouveau/SConscript', + #'targets/xorg-radeon/SConscript', + 'targets/xorg-vmwgfx/SConscript', ]) -if env['xorg'] and env['drm']: - SConscript([ - #'targets/xorg-i915/SConscript', - #'targets/xorg-i965/SConscript', - #'targets/xorg-nouveau/SConscript', - #'targets/xorg-radeon/SConscript', - 'targets/xorg-vmwgfx/SConscript', - ]) - # # Unit tests & tools # -if env['platform'] != 'embedded': +if not env['embedded']: SConscript('tests/unit/SConscript') SConscript('tests/graw/SConscript') diff --git a/src/gallium/auxiliary/os/os_memory.h b/src/gallium/auxiliary/os/os_memory.h index 556662d35e1..91a84a24bc8 100644 --- a/src/gallium/auxiliary/os/os_memory.h +++ b/src/gallium/auxiliary/os/os_memory.h @@ -39,7 +39,7 @@ #include "pipe/p_compiler.h" -#if defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_SUBSYSTEM_EMBEDDED) #ifdef __cplusplus extern "C" { diff --git a/src/gallium/auxiliary/os/os_misc.h b/src/gallium/auxiliary/os/os_misc.h index d59f9819fec..48522dac4d7 100644 --- a/src/gallium/auxiliary/os/os_misc.h +++ b/src/gallium/auxiliary/os/os_misc.h @@ -58,8 +58,6 @@ extern "C" { # define os_break() __debugbreak() #elif defined(PIPE_OS_UNIX) # define os_break() kill(getpid(), SIGTRAP) -#elif defined(PIPE_OS_EMBEDDED) -void os_break(void); #else # define os_break() abort() #endif @@ -70,8 +68,6 @@ void os_break(void); */ #if defined(DEBUG) || defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT) # define os_abort() os_break() -#elif defined(PIPE_OS_EMBEDDED) -void os_abort(void); #else # define os_abort() abort() #endif diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h index 6b4281ad661..8f1245bff55 100644 --- a/src/gallium/auxiliary/os/os_thread.h +++ b/src/gallium/auxiliary/os/os_thread.h @@ -40,7 +40,7 @@ #include "util/u_debug.h" /* for assert */ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) #include /* POSIX threads headers */ #include /* for perror() */ @@ -314,7 +314,7 @@ typedef int64_t pipe_condvar; * pipe_barrier */ -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) typedef pthread_barrier_t pipe_barrier; @@ -442,7 +442,7 @@ pipe_semaphore_wait(pipe_semaphore *sema) */ typedef struct { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) pthread_key_t key; #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) DWORD key; @@ -457,7 +457,7 @@ typedef struct { static INLINE void pipe_tsd_init(pipe_tsd *tsd) { -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { perror("pthread_key_create(): failed to allocate key for thread specific data"); exit(-1); @@ -474,7 +474,7 @@ pipe_tsd_get(pipe_tsd *tsd) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) return pthread_getspecific(tsd->key); #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) assert(0); @@ -491,7 +491,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value) if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { pipe_tsd_init(tsd); } -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) if (pthread_setspecific(tsd->key, value) != 0) { perror("pthread_set_specific() failed"); exit(-1); diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c index 325f316784c..73d86296d91 100644 --- a/src/gallium/auxiliary/os/os_time.c +++ b/src/gallium/auxiliary/os/os_time.c @@ -35,8 +35,6 @@ #include "pipe/p_config.h" -#if !defined(PIPE_OS_EMBEDDED) - #if defined(PIPE_OS_UNIX) # include /* timeval */ #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) @@ -123,6 +121,3 @@ os_time_sleep(int64_t usecs) } #endif - - -#endif /* !PIPE_OS_EMBEDDED */ diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 36ce4b57713..004df439ff5 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -48,7 +48,7 @@ void _debug_vprintf(const char *format, va_list ap) { -#if defined(PIPE_OS_WINDOWS) || defined(PIPE_OS_EMBEDDED) +#if defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_EMBEDDED) /* We buffer until we find a newline. */ static char buf[4096] = {'\0'}; size_t len = strlen(buf); diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index c10a8cbc12c..d6b20ceb5ce 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -79,7 +79,7 @@ llvmpipe = env.ConvenienceLibrary( env.Alias('llvmpipe', llvmpipe) -if env['platform'] != 'embedded': +if not env['embedded']: env = env.Clone() env.Prepend(LIBS = [llvmpipe] + gallium) diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 036a6e0c379..4b2ae1436ea 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -423,7 +423,7 @@ llvmpipe_create_screen(struct sw_winsys *winsys) lp_jit_screen_init(screen); screen->num_threads = util_cpu_caps.nr_cpus > 1 ? util_cpu_caps.nr_cpus : 0; -#ifdef PIPE_OS_EMBEDDED +#ifdef PIPE_SUBSYSTEM_EMBEDDED screen->num_threads = 0; #endif screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads); diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h index 40f6f2bcb5f..eea3d79e64b 100644 --- a/src/gallium/include/pipe/p_config.h +++ b/src/gallium/include/pipe/p_config.h @@ -134,8 +134,6 @@ #error Unknown Endianness #endif -#if !defined(PIPE_OS_EMBEDDED) - /* * Auto-detect the operating system family. * @@ -222,7 +220,5 @@ #endif #endif /* PIPE_OS_WINDOWS */ -#endif /* !PIPE_OS_EMBEDDED */ - #endif /* P_CONFIG_H_ */ diff --git a/src/glsl/SConscript b/src/glsl/SConscript index c3255835fb4..1441cc74bd8 100644 --- a/src/glsl/SConscript +++ b/src/glsl/SConscript @@ -102,7 +102,7 @@ if env['msvc']: env.Prepend(CPPPATH = ['#/src/getopt']) env.PrependUnique(LIBS = [getopt]) -if env['crosscompile'] and env['platform'] != 'embedded': +if env['crosscompile'] and not env['embedded']: Import('builtin_glsl_function') else: # Copy these files to avoid generation object files into src/mesa/program @@ -156,7 +156,7 @@ Export('glsl') # Skip building these programs as they will cause SCons error "Two environments # with different actions were specified for the same target" -if env['crosscompile'] or env['platform'] == 'embedded': +if env['crosscompile'] or env['embedded']: Return() env = env.Clone() -- cgit v1.2.3 From de77324d8f14951e4dc17f570e49451a0cd33121 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 9 Jun 2011 13:31:32 -0700 Subject: linker: Reject shaders that use too many varyings Previously it was up to the driver or later code generator to reject these shaders. It turns out that nobody did this. This will need changes to support geometry shaders. NOTE: This is a candidate for the stable branches. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=37743 Reviewed-by: Kenneth Graunke --- src/glsl/linker.cpp | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 255edc6a76f..b6479e7a3a4 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1405,8 +1405,9 @@ demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode) } -void -assign_varying_locations(struct gl_shader_program *prog, +bool +assign_varying_locations(struct gl_context *ctx, + struct gl_shader_program *prog, gl_shader *producer, gl_shader *consumer) { /* FINISHME: Set dynamically when geometry shader support is added. */ @@ -1462,6 +1463,8 @@ assign_varying_locations(struct gl_shader_program *prog, } } + unsigned varying_vectors = 0; + foreach_list(node, consumer->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); @@ -1492,8 +1495,32 @@ assign_varying_locations(struct gl_shader_program *prog, * value is written by the previous stage. */ var->mode = ir_var_auto; + } else { + /* The packing rules are used for vertex shader inputs are also used + * for fragment shader inputs. + */ + varying_vectors += count_attribute_slots(var->type); } } + + if (ctx->API == API_OPENGLES2 || prog->Version == 100) { + if (varying_vectors > ctx->Const.MaxVarying) { + linker_error_printf(prog, "shader uses too many varying vectors " + "(%u > %u)\n", + varying_vectors, ctx->Const.MaxVarying); + return false; + } + } else { + const unsigned float_components = varying_vectors * 4; + if (float_components > ctx->Const.MaxVarying * 4) { + linker_error_printf(prog, "shader uses too many varying components " + "(%u > %u)\n", + float_components, ctx->Const.MaxVarying * 4); + return false; + } + } + + return true; } @@ -1666,9 +1693,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (prog->_LinkedShaders[i] == NULL) continue; - assign_varying_locations(prog, - prog->_LinkedShaders[prev], - prog->_LinkedShaders[i]); + if (!assign_varying_locations(ctx, prog, + prog->_LinkedShaders[prev], + prog->_LinkedShaders[i])) { + prog->LinkStatus = false; + goto done; + } + prev = i; } -- cgit v1.2.3 From 935e7e41266186c454e08c80aff40c34084d83c6 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Wed, 15 Jun 2011 16:26:10 -0700 Subject: glsl: Flagged extension EXT_texture3D as "supported" in the builtin compiler. Previously, the builtins in OES_texture_3D.{frag,vert} were only compiling properly as a consequence of bug 38015, which allows unsupported extensions to be enabled. This fix eliminates the builtin compiler's reliance on bug 38015, so that bug 38015 can be fixed. --- src/glsl/main.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/glsl') diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp index 096da93dcef..7952bb1a3e3 100644 --- a/src/glsl/main.cpp +++ b/src/glsl/main.cpp @@ -76,6 +76,7 @@ initialize_context(struct gl_context *ctx, gl_api api) ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; ctx->Extensions.EXT_texture_array = GL_TRUE; ctx->Extensions.NV_texture_rectangle = GL_TRUE; + ctx->Extensions.EXT_texture3D = GL_TRUE; /* GLSL 1.30 isn't fully supported, but we need to advertise 1.30 so that * the built-in functions for 1.30 can be built. -- cgit v1.2.3 From d2c6cef18aa37d197eb323a0795969d271d02819 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 2 Jun 2011 12:42:48 -0700 Subject: glsl: Fix depth unbalancing problem in if-statement flattening Previously, if max_depth were 1, the following code would see the first if-statement (correctly) not get flattened, but the second if-statement would (incorrectly) get flattened: void main() { if (a) gl_Position = vec4(0); if (b) gl_Position = vec4(1); } This is because the visit_leave(ir_if*) method would not decrement the depth before returning on the first if-statement. NOTE: This is a candidate for the 7.10 and 7.11 branches. Reviewed-by: Kenneth Graunke --- src/glsl/lower_if_to_cond_assign.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/lower_if_to_cond_assign.cpp b/src/glsl/lower_if_to_cond_assign.cpp index e3a1065d996..b637eb4fe1d 100644 --- a/src/glsl/lower_if_to_cond_assign.cpp +++ b/src/glsl/lower_if_to_cond_assign.cpp @@ -149,11 +149,9 @@ ir_visitor_status ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir) { /* Only flatten when beyond the GPU's maximum supported nesting depth. */ - if (this->depth <= this->max_depth) + if (this->depth-- <= this->max_depth) return visit_continue; - this->depth--; - bool found_control_flow = false; ir_variable *cond_var; ir_assignment *assign; -- cgit v1.2.3 From b078aad8ab22d840456688480a8c27d4664297ce Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Tue, 28 Jun 2011 09:42:24 -0700 Subject: glsl: permit explicit locations on fragment shader outputs, not inputs From the OpenGL docs for GL_ARB_explicit_attrib_location: This extension provides a method to pre-assign attribute locations to named vertex shader inputs and color numbers to named fragment shader outputs. This was accidentally implemented for fragment shader inputs. This patch fixes it to apply to fragment shader outputs. Fixes piglit tests spec/ARB_explicit_attrib_location/1.{10,20}/compiler/layout-{01,03,06,07,08,09,10}.frag Reviewed-by: Ian Romanick NOTE: This is a candidate for the 7.10 and 7.11 branches. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38624 --- src/glsl/ast_to_hir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 3b87f0d56de..35cb2067060 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1940,7 +1940,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, break; case fragment_shader: - if (!global_scope || (var->mode != ir_var_in)) { + if (!global_scope || (var->mode != ir_var_out)) { fail = true; string = "output"; } -- cgit v1.2.3 From 9c4445de6e69d021491361d884bf172c05189d61 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Fri, 24 Jun 2011 12:33:30 -0700 Subject: glsl: Changed extension enable bits to bools. These were previously 1-bit-wide bitfields. Changing them to bools has a negligible performance impact, and allows them to be accessed by offset as well as by direct structure access. NOTE: This is a candidate for the 7.10 and 7.11 branches. Reviewed-by: Ian Romanick --- src/glsl/glsl_parser_extras.h | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h index 878d2ae3f4d..2f4d3cba77f 100644 --- a/src/glsl/glsl_parser_extras.h +++ b/src/glsl/glsl_parser_extras.h @@ -156,28 +156,28 @@ struct _mesa_glsl_parse_state { * \name Enable bits for GLSL extensions */ /*@{*/ - unsigned ARB_draw_buffers_enable:1; - unsigned ARB_draw_buffers_warn:1; - unsigned ARB_draw_instanced_enable:1; - unsigned ARB_draw_instanced_warn:1; - unsigned ARB_explicit_attrib_location_enable:1; - unsigned ARB_explicit_attrib_location_warn:1; - unsigned ARB_fragment_coord_conventions_enable:1; - unsigned ARB_fragment_coord_conventions_warn:1; - unsigned ARB_texture_rectangle_enable:1; - unsigned ARB_texture_rectangle_warn:1; - unsigned EXT_texture_array_enable:1; - unsigned EXT_texture_array_warn:1; - unsigned ARB_shader_texture_lod_enable:1; - unsigned ARB_shader_texture_lod_warn:1; - unsigned ARB_shader_stencil_export_enable:1; - unsigned ARB_shader_stencil_export_warn:1; - unsigned AMD_conservative_depth_enable:1; - unsigned AMD_conservative_depth_warn:1; - unsigned AMD_shader_stencil_export_enable:1; - unsigned AMD_shader_stencil_export_warn:1; - unsigned OES_texture_3D_enable:1; - unsigned OES_texture_3D_warn:1; + bool ARB_draw_buffers_enable; + bool ARB_draw_buffers_warn; + bool ARB_draw_instanced_enable; + bool ARB_draw_instanced_warn; + bool ARB_explicit_attrib_location_enable; + bool ARB_explicit_attrib_location_warn; + bool ARB_fragment_coord_conventions_enable; + bool ARB_fragment_coord_conventions_warn; + bool ARB_texture_rectangle_enable; + bool ARB_texture_rectangle_warn; + bool EXT_texture_array_enable; + bool EXT_texture_array_warn; + bool ARB_shader_texture_lod_enable; + bool ARB_shader_texture_lod_warn; + bool ARB_shader_stencil_export_enable; + bool ARB_shader_stencil_export_warn; + bool AMD_conservative_depth_enable; + bool AMD_conservative_depth_warn; + bool AMD_shader_stencil_export_enable; + bool AMD_shader_stencil_export_warn; + bool OES_texture_3D_enable; + bool OES_texture_3D_warn; /*@}*/ /** Extensions supported by the OpenGL implementation. */ -- cgit v1.2.3 From 3097715d41da4b725b7ce9f9d5bbc0f684cbf0a6 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Fri, 24 Jun 2011 15:34:04 -0700 Subject: glsl: Rewrote _mesa_glsl_process_extension to use table-driven logic. Instead of using a chain of manually maintained if/else blocks to handle "#extension" directives, we now consult a table that specifies, for each extension, the circumstances under which it is available, and what flags in _mesa_glsl_parse_state need to be set in order to activate it. This makes it easier to add new GLSL extensions in the future, and fixes the following bugs: - Previously, _mesa_glsl_process_extension would sometimes set the "_enable" and "_warn" flags for an extension before checking whether the extension was supported by the driver; as a result, specifying "enable" behavior for an unsupported extension would sometimes cause front-end support for that extension to be switched on in spite of the fact that back-end support was not available, leading to strange failures, such as those in https://bugs.freedesktop.org/show_bug.cgi?id=38015. - "#extension all: warn" and "#extension all: disable" had no effect. Notes: - All extensions are currently marked as unavailable in geometry shaders. This should not have any adverse effects since geometry shaders aren't supported yet. When we return to working on geometry shader support, we'll need to update the table for those extensions that are available in geometry shaders. - Previous to this commit, if a shader mentioned ARB_shader_texture_lod, extension ARB_texture_rectangle would be automatically turned on in order to ensure that the types sampler2DRect and sampler2DRectShadow would be defined. This was unnecessary, because (a) ARB_shader_texture_lod works perfectly well without those types provided that the builtin functions that reference them are not called, and (b) ARB_texture_rectangle is enabled by default in non-ES contexts anyway. I eliminated this unnecessary behavior in order to make the behavior of all extensions consistent. NOTE: This is a candidate for the 7.10 and 7.11 branches. Reviewed-by: Ian Romanick --- src/glsl/glsl_parser_extras.cpp | 327 ++++++++++++++++++++++++++-------------- 1 file changed, 218 insertions(+), 109 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp index d9aa300bbe4..cc781378d76 100644 --- a/src/glsl/glsl_parser_extras.cpp +++ b/src/glsl/glsl_parser_extras.cpp @@ -165,133 +165,242 @@ _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, } +/** + * Enum representing the possible behaviors that can be specified in + * an #extension directive. + */ +enum ext_behavior { + extension_disable, + extension_enable, + extension_require, + extension_warn +}; + +/** + * Element type for _mesa_glsl_supported_extensions + */ +struct _mesa_glsl_extension { + /** + * Name of the extension when referred to in a GLSL extension + * statement + */ + const char *name; + + /** True if this extension is available to vertex shaders */ + bool avail_in_VS; + + /** True if this extension is available to geometry shaders */ + bool avail_in_GS; + + /** True if this extension is available to fragment shaders */ + bool avail_in_FS; + + /** True if this extension is available to desktop GL shaders */ + bool avail_in_GL; + + /** True if this extension is available to GLES shaders */ + bool avail_in_ES; + + /** + * Flag in the gl_extensions struct indicating whether this + * extension is supported by the driver, or + * &gl_extensions::dummy_true if supported by all drivers. + * + * Note: the type (GLboolean gl_extensions::*) is a "pointer to + * member" type, the type-safe alternative to the "offsetof" macro. + * In a nutshell: + * + * - foo bar::* p declares p to be an "offset" to a field of type + * foo that exists within struct bar + * - &bar::baz computes the "offset" of field baz within struct bar + * - x.*p accesses the field of x that exists at "offset" p + * - x->*p is equivalent to (*x).*p + */ + const GLboolean gl_extensions::* supported_flag; + + /** + * Flag in the _mesa_glsl_parse_state struct that should be set + * when this extension is enabled. + * + * See note in _mesa_glsl_extension::supported_flag about "pointer + * to member" types. + */ + bool _mesa_glsl_parse_state::* enable_flag; + + /** + * Flag in the _mesa_glsl_parse_state struct that should be set + * when the shader requests "warn" behavior for this extension. + * + * See note in _mesa_glsl_extension::supported_flag about "pointer + * to member" types. + */ + bool _mesa_glsl_parse_state::* warn_flag; + + + bool compatible_with_state(const _mesa_glsl_parse_state *state) const; + void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const; +}; + +#define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \ + { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \ + &_mesa_glsl_parse_state::NAME##_enable, \ + &_mesa_glsl_parse_state::NAME##_warn } + +/** + * Table of extensions that can be enabled/disabled within a shader, + * and the conditions under which they are supported. + */ +static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { + /* target availability API availability */ + /* name VS GS FS GL ES supported flag */ + EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true), + EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced), + EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location), + EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions), + EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true), + EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array), + EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod), + EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), + EXT(AMD_conservative_depth, true, false, true, true, false, AMD_conservative_depth), + EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export), + EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D), +}; + +#undef EXT + + +/** + * Determine whether a given extension is compatible with the target, + * API, and extension information in the current parser state. + */ +bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state * + state) const +{ + /* Check that this extension matches the type of shader we are + * compiling to. + */ + switch (state->target) { + case vertex_shader: + if (!this->avail_in_VS) { + return false; + } + break; + case geometry_shader: + if (!this->avail_in_GS) { + return false; + } + break; + case fragment_shader: + if (!this->avail_in_FS) { + return false; + } + break; + default: + assert (!"Unrecognized shader target"); + return false; + } + + /* Check that this extension matches whether we are compiling + * for desktop GL or GLES. + */ + if (state->es_shader) { + if (!this->avail_in_ES) return false; + } else { + if (!this->avail_in_GL) return false; + } + + /* Check that this extension is supported by the OpenGL + * implementation. + * + * Note: the ->* operator indexes into state->extensions by the + * offset this->supported_flag. See + * _mesa_glsl_extension::supported_flag for more info. + */ + return state->extensions->*(this->supported_flag); +} + +/** + * Set the appropriate flags in the parser state to establish the + * given behavior for this extension. + */ +void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state, + ext_behavior behavior) const +{ + /* Note: the ->* operator indexes into state by the + * offsets this->enable_flag and this->warn_flag. See + * _mesa_glsl_extension::supported_flag for more info. + */ + state->*(this->enable_flag) = (behavior != extension_disable); + state->*(this->warn_flag) = (behavior == extension_warn); +} + +/** + * Find an extension by name in _mesa_glsl_supported_extensions. If + * the name is not found, return NULL. + */ +static const _mesa_glsl_extension *find_extension(const char *name) +{ + for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) { + if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) { + return &_mesa_glsl_supported_extensions[i]; + } + } + return NULL; +} + + bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, - const char *behavior, YYLTYPE *behavior_locp, + const char *behavior_string, YYLTYPE *behavior_locp, _mesa_glsl_parse_state *state) { - enum { - extension_disable, - extension_enable, - extension_require, - extension_warn - } ext_mode; - - if (strcmp(behavior, "warn") == 0) { - ext_mode = extension_warn; - } else if (strcmp(behavior, "require") == 0) { - ext_mode = extension_require; - } else if (strcmp(behavior, "enable") == 0) { - ext_mode = extension_enable; - } else if (strcmp(behavior, "disable") == 0) { - ext_mode = extension_disable; + ext_behavior behavior; + if (strcmp(behavior_string, "warn") == 0) { + behavior = extension_warn; + } else if (strcmp(behavior_string, "require") == 0) { + behavior = extension_require; + } else if (strcmp(behavior_string, "enable") == 0) { + behavior = extension_enable; + } else if (strcmp(behavior_string, "disable") == 0) { + behavior = extension_disable; } else { _mesa_glsl_error(behavior_locp, state, "Unknown extension behavior `%s'", - behavior); + behavior_string); return false; } - bool unsupported = false; - if (strcmp(name, "all") == 0) { - if ((ext_mode == extension_enable) || (ext_mode == extension_require)) { + if ((behavior == extension_enable) || (behavior == extension_require)) { _mesa_glsl_error(name_locp, state, "Cannot %s all extensions", - (ext_mode == extension_enable) + (behavior == extension_enable) ? "enable" : "require"); return false; - } - } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) { - /* This extension is only supported in fragment shaders. - */ - if (state->target != fragment_shader) { - unsupported = true; } else { - state->ARB_draw_buffers_enable = (ext_mode != extension_disable); - state->ARB_draw_buffers_warn = (ext_mode == extension_warn); + for (unsigned i = 0; + i < Elements(_mesa_glsl_supported_extensions); ++i) { + const _mesa_glsl_extension *extension + = &_mesa_glsl_supported_extensions[i]; + if (extension->compatible_with_state(state)) { + _mesa_glsl_supported_extensions[i].set_flags(state, behavior); + } + } } - } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) { - state->ARB_draw_instanced_enable = (ext_mode != extension_disable); - state->ARB_draw_instanced_warn = (ext_mode == extension_warn); - - /* This extension is only supported in vertex shaders. - */ - unsupported = (state->target != vertex_shader) - || !state->extensions->ARB_draw_instanced; - } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) { - state->ARB_explicit_attrib_location_enable = - (ext_mode != extension_disable); - state->ARB_explicit_attrib_location_warn = - (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_explicit_attrib_location; - } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) { - state->ARB_fragment_coord_conventions_enable = - (ext_mode != extension_disable); - state->ARB_fragment_coord_conventions_warn = - (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_fragment_coord_conventions; - } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) { - state->ARB_texture_rectangle_enable = (ext_mode != extension_disable); - state->ARB_texture_rectangle_warn = (ext_mode == extension_warn); - } else if (strcmp(name, "GL_EXT_texture_array") == 0) { - state->EXT_texture_array_enable = (ext_mode != extension_disable); - state->EXT_texture_array_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->EXT_texture_array; - } else if (strcmp(name, "GL_ARB_shader_texture_lod") == 0) { - /* Force ARB_texture_rectangle to be on so sampler2DRects are defined */ - state->ARB_texture_rectangle_enable = true; - - state->ARB_shader_texture_lod_enable = (ext_mode != extension_disable); - state->ARB_shader_texture_lod_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->ARB_shader_texture_lod; - } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) { - state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable); - state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn); - - /* This extension is only supported in fragment shaders. - */ - unsupported = (state->target != fragment_shader) - || !state->extensions->ARB_shader_stencil_export; - } else if (strcmp(name, "GL_AMD_conservative_depth") == 0) { - /* The AMD_conservative spec does not forbid requiring the extension in - * the vertex shader. - */ - state->AMD_conservative_depth_enable = (ext_mode != extension_disable); - state->AMD_conservative_depth_warn = (ext_mode == extension_warn); - unsupported = !state->extensions->AMD_conservative_depth; - } else if (strcmp(name, "GL_AMD_shader_stencil_export") == 0) { - state->AMD_shader_stencil_export_enable = (ext_mode != extension_disable); - state->AMD_shader_stencil_export_warn = (ext_mode == extension_warn); - - /* This extension is only supported in fragment shaders. - * Both the ARB and AMD variants share the same ARB flag - * in gl_extensions. - */ - unsupported = (state->target != fragment_shader) - || !state->extensions->ARB_shader_stencil_export; - } else if (strcmp(name, "GL_OES_texture_3D") == 0 && state->es_shader) { - state->OES_texture_3D_enable = (ext_mode != extension_disable); - state->OES_texture_3D_warn = (ext_mode == extension_warn); - - unsupported = !state->extensions->EXT_texture3D; } else { - unsupported = true; - } - - if (unsupported) { - static const char *const fmt = "extension `%s' unsupported in %s shader"; - - if (ext_mode == extension_require) { - _mesa_glsl_error(name_locp, state, fmt, - name, _mesa_glsl_shader_target_name(state->target)); - return false; + const _mesa_glsl_extension *extension = find_extension(name); + if (extension && extension->compatible_with_state(state)) { + extension->set_flags(state, behavior); } else { - _mesa_glsl_warning(name_locp, state, fmt, - name, _mesa_glsl_shader_target_name(state->target)); + static const char *const fmt = "extension `%s' unsupported in %s shader"; + + if (behavior == extension_require) { + _mesa_glsl_error(name_locp, state, fmt, + name, _mesa_glsl_shader_target_name(state->target)); + return false; + } else { + _mesa_glsl_warning(name_locp, state, fmt, + name, _mesa_glsl_shader_target_name(state->target)); + } } } -- cgit v1.2.3 From e75b5954db52723a8590cd321b1998a079e9c1d4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 Jun 2011 12:11:35 -0700 Subject: glsl: Drop explicit types of lower_mat_op_to_vec expressions. The constructor can figure it out for us these days. Reviewed-by: Kenneth Graunke --- src/glsl/lower_mat_op_to_vec.cpp | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index 8cbbfa713c9..bf3915ef95f 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -144,7 +144,6 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - a->type, a, b); @@ -156,11 +155,9 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, b = get_element(b_var, b_col, i); mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - a->type, a, b); expr = new(mem_ctx) ir_expression(ir_binop_add, - a->type, expr, mul_expr); } @@ -186,7 +183,6 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - result_var->type, a, b); @@ -198,13 +194,9 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, b = get_element(b_var, 0, i); mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - result_var->type, a, b); - expr = new(mem_ctx) ir_expression(ir_binop_add, - result_var->type, - expr, - mul_expr); + expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); } ir_rvalue *result = new(mem_ctx) ir_dereference_variable(result_var); @@ -232,7 +224,6 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var, result = new(mem_ctx) ir_swizzle(result, i, 0, 0, 0, 1); column_expr = new(mem_ctx) ir_expression(ir_binop_dot, - result->type, a, b); @@ -258,7 +249,6 @@ ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var, ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(ir_binop_mul, - result->type, a, b); @@ -307,8 +297,7 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, ir_dereference *const op1 = get_column(b_var, i); ir_expression *const cmp = - new(this->mem_ctx) ir_expression(ir_binop_any_nequal, - glsl_type::bool_type, op0, op1); + new(this->mem_ctx) ir_expression(ir_binop_any_nequal, op0, op1); ir_dereference *const lhs = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); @@ -319,17 +308,11 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, this->base_ir->insert_before(assign); } - ir_rvalue *const val = - new(this->mem_ctx) ir_dereference_variable(tmp_bvec); - - ir_expression *any = - new(this->mem_ctx) ir_expression(ir_unop_any, glsl_type::bool_type, - val, NULL); + ir_rvalue *const val = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); + ir_expression *any = new(this->mem_ctx) ir_expression(ir_unop_any, val); if (test_equal) - any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, - glsl_type::bool_type, - any, NULL); + any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any); ir_rvalue *const result = new(this->mem_ctx) ir_dereference_variable(result_var); @@ -406,10 +389,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) ir_expression *column_expr; ir_assignment *column_assign; - column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - result->type, - op0, - NULL); + column_expr = new(mem_ctx) ir_expression(orig_expr->operation, op0); column_assign = new(mem_ctx) ir_assignment(result, column_expr, @@ -438,7 +418,6 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - result->type, op0, op1); -- cgit v1.2.3 From a47fd5c27de2b2d61776faa524f9b7ab1c915cde Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 Jun 2011 12:16:03 -0700 Subject: glsl: Move get_{column,element} to expression args. I think this makes the code more obvious by moving the declarations to their single usage (now that we aren't using them to get at the ->type field for expression constructors). Reviewed-by: Kenneth Graunke --- src/glsl/lower_mat_op_to_vec.cpp | 65 ++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 43 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index bf3915ef95f..cda72ae91c3 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -139,24 +139,18 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, ir_expression *expr; for (b_col = 0; b_col < b_var->type->matrix_columns; b_col++) { - ir_rvalue *a = get_column(a_var, 0); - ir_rvalue *b = get_element(b_var, b_col, 0); - /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - a, - b); + get_column(a_var, 0), + get_element(b_var, b_col, 0)); /* following columns */ for (i = 1; i < a_var->type->matrix_columns; i++) { ir_expression *mul_expr; - a = get_column(a_var, i); - b = get_element(b_var, b_col, i); - mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - a, - b); + get_column(a_var, i), + get_element(b_var, b_col, i)); expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); @@ -176,26 +170,21 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, ir_variable *b_var) { int i; - ir_rvalue *a = get_column(a_var, 0); - ir_rvalue *b = get_element(b_var, 0, 0); ir_assignment *assign; ir_expression *expr; /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - a, - b); + get_column(a_var, 0), + get_element(b_var, 0, 0)); /* following columns */ for (i = 1; i < a_var->type->matrix_columns; i++) { ir_expression *mul_expr; - a = get_column(a_var, i); - b = get_element(b_var, 0, i); - mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - a, - b); + get_column(a_var, i), + get_element(b_var, 0, i)); expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); } @@ -214,8 +203,6 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var, int i; for (i = 0; i < b_var->type->matrix_columns; i++) { - ir_rvalue *a = new(mem_ctx) ir_dereference_variable(a_var); - ir_rvalue *b = get_column(b_var, i); ir_rvalue *result; ir_expression *column_expr; ir_assignment *column_assign; @@ -224,8 +211,8 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var, result = new(mem_ctx) ir_swizzle(result, i, 0, 0, 0, 1); column_expr = new(mem_ctx) ir_expression(ir_binop_dot, - a, - b); + new(mem_ctx) ir_dereference_variable(a_var), + get_column(b_var, i)); column_assign = new(mem_ctx) ir_assignment(result, column_expr, @@ -242,17 +229,14 @@ ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var, int i; for (i = 0; i < a_var->type->matrix_columns; i++) { - ir_rvalue *a = get_column(a_var, i); - ir_rvalue *b = new(mem_ctx) ir_dereference_variable(b_var); - ir_rvalue *result = get_column(result_var, i); ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(ir_binop_mul, - a, - b); + get_column(a_var, i), + new(mem_ctx) ir_dereference_variable(b_var)); - column_assign = new(mem_ctx) ir_assignment(result, + column_assign = new(mem_ctx) ir_assignment(get_column(result_var, i), column_expr, NULL); base_ir->insert_before(column_assign); @@ -293,11 +277,10 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, this->base_ir->insert_before(tmp_bvec); for (unsigned i = 0; i < columns; i++) { - ir_dereference *const op0 = get_column(a_var, i); - ir_dereference *const op1 = get_column(b_var, i); - ir_expression *const cmp = - new(this->mem_ctx) ir_expression(ir_binop_any_nequal, op0, op1); + new(this->mem_ctx) ir_expression(ir_binop_any_nequal, + get_column(a_var, i), + get_column(b_var, i)); ir_dereference *const lhs = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); @@ -384,14 +367,13 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) /* Apply the operation to each column.*/ for (i = 0; i < matrix_columns; i++) { - ir_rvalue *op0 = get_column(op_var[0], i); - ir_dereference *result = get_column(result_var, i); ir_expression *column_expr; ir_assignment *column_assign; - column_expr = new(mem_ctx) ir_expression(orig_expr->operation, op0); + column_expr = new(mem_ctx) ir_expression(orig_expr->operation, + get_column(op_var[0], i)); - column_assign = new(mem_ctx) ir_assignment(result, + column_assign = new(mem_ctx) ir_assignment(get_column(result_var, i), column_expr, NULL, mask); @@ -411,17 +393,14 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) * if available. */ for (i = 0; i < matrix_columns; i++) { - ir_rvalue *op0 = get_column(op_var[0], i); - ir_rvalue *op1 = get_column(op_var[1], i); - ir_dereference *result = get_column(result_var, i); ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - op0, - op1); + get_column(op_var[0], i), + get_column(op_var[1], i)); - column_assign = new(mem_ctx) ir_assignment(result, + column_assign = new(mem_ctx) ir_assignment(get_column(result_var, i), column_expr, NULL, mask); -- cgit v1.2.3 From 408377aed1dfae30605709fe1a134880a0386aa8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 Jun 2011 14:19:57 -0700 Subject: glsl: Rename lower_mat_op_to_vec operands/results to be less hungarian. This awkward typing was to avoid shadowing the function argument (the matrix) with the temporary deref (the column) before the get_column()/get_element()s were moved into the expression/assignment constructors. They're about to become not-variables, so the current names had to go. This change is almost mechanical (other than column_expr), so it should make the next diff clearer. Reviewed-by: Kenneth Graunke --- src/glsl/lower_mat_op_to_vec.cpp | 148 +++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 74 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index cda72ae91c3..6d2bc0100f8 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -48,16 +48,16 @@ public: ir_dereference *get_column(ir_variable *var, int col); ir_rvalue *get_element(ir_variable *var, int col, int row); - void do_mul_mat_mat(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_mat_vec(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_vec_mat(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_mul_mat_scalar(ir_variable *result_var, - ir_variable *a_var, ir_variable *b_var); - void do_equal_mat_mat(ir_variable *result_var, ir_variable *a_var, - ir_variable *b_var, bool test_equal); + void do_mul_mat_mat(ir_variable *result, + ir_variable *a, ir_variable *b); + void do_mul_mat_vec(ir_variable *result, + ir_variable *a, ir_variable *b); + void do_mul_vec_mat(ir_variable *result, + ir_variable *a, ir_variable *b); + void do_mul_mat_scalar(ir_variable *result, + ir_variable *a, ir_variable *b); + void do_equal_mat_mat(ir_variable *result, ir_variable *a, + ir_variable *b, bool test_equal); void *mem_ctx; bool made_progress; @@ -131,26 +131,26 @@ ir_mat_op_to_vec_visitor::get_column(ir_variable *var, int row) void ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) + ir_variable *a, + ir_variable *b) { int b_col, i; ir_assignment *assign; ir_expression *expr; - for (b_col = 0; b_col < b_var->type->matrix_columns; b_col++) { + for (b_col = 0; b_col < b->type->matrix_columns; b_col++) { /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - get_column(a_var, 0), - get_element(b_var, b_col, 0)); + get_column(a, 0), + get_element(b, b_col, 0)); /* following columns */ - for (i = 1; i < a_var->type->matrix_columns; i++) { + for (i = 1; i < a->type->matrix_columns; i++) { ir_expression *mul_expr; mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - get_column(a_var, i), - get_element(b_var, b_col, i)); + get_column(a, i), + get_element(b, b_col, i)); expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); @@ -166,8 +166,8 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, void ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) + ir_variable *a, + ir_variable *b) { int i; ir_assignment *assign; @@ -175,16 +175,16 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, /* first column */ expr = new(mem_ctx) ir_expression(ir_binop_mul, - get_column(a_var, 0), - get_element(b_var, 0, 0)); + get_column(a, 0), + get_element(b, 0, 0)); /* following columns */ - for (i = 1; i < a_var->type->matrix_columns; i++) { + for (i = 1; i < a->type->matrix_columns; i++) { ir_expression *mul_expr; mul_expr = new(mem_ctx) ir_expression(ir_binop_mul, - get_column(a_var, i), - get_element(b_var, 0, i)); + get_column(a, i), + get_element(b, 0, i)); expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); } @@ -196,25 +196,25 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, } void -ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result, + ir_variable *a, + ir_variable *b) { int i; - for (i = 0; i < b_var->type->matrix_columns; i++) { - ir_rvalue *result; + for (i = 0; i < b->type->matrix_columns; i++) { + ir_rvalue *column_result; ir_expression *column_expr; ir_assignment *column_assign; - result = new(mem_ctx) ir_dereference_variable(result_var); - result = new(mem_ctx) ir_swizzle(result, i, 0, 0, 0, 1); + column_result = new(mem_ctx) ir_dereference_variable(result); + column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1); column_expr = new(mem_ctx) ir_expression(ir_binop_dot, - new(mem_ctx) ir_dereference_variable(a_var), - get_column(b_var, i)); + new(mem_ctx) ir_dereference_variable(a), + get_column(b, i)); - column_assign = new(mem_ctx) ir_assignment(result, + column_assign = new(mem_ctx) ir_assignment(column_result, column_expr, NULL); base_ir->insert_before(column_assign); @@ -222,21 +222,21 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var, } void -ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var) +ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result, + ir_variable *a, + ir_variable *b) { int i; - for (i = 0; i < a_var->type->matrix_columns; i++) { + for (i = 0; i < a->type->matrix_columns; i++) { ir_expression *column_expr; ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(ir_binop_mul, - get_column(a_var, i), - new(mem_ctx) ir_dereference_variable(b_var)); + get_column(a, i), + new(mem_ctx) ir_dereference_variable(b)); - column_assign = new(mem_ctx) ir_assignment(get_column(result_var, i), + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), column_expr, NULL); base_ir->insert_before(column_assign); @@ -245,8 +245,8 @@ ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var, void ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, - ir_variable *a_var, - ir_variable *b_var, + ir_variable *a, + ir_variable *b, bool test_equal) { /* This essentially implements the following GLSL: @@ -267,7 +267,7 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, * a[3] != b[3]); * } */ - const unsigned columns = a_var->type->matrix_columns; + const unsigned columns = a->type->matrix_columns; const glsl_type *const bvec_type = glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1); @@ -279,8 +279,8 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, for (unsigned i = 0; i < columns; i++) { ir_expression *const cmp = new(this->mem_ctx) ir_expression(ir_binop_any_nequal, - get_column(a_var, i), - get_column(b_var, i)); + get_column(a, i), + get_column(b, i)); ir_dereference *const lhs = new(this->mem_ctx) ir_dereference_variable(tmp_bvec); @@ -324,7 +324,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) { ir_expression *orig_expr = orig_assign->rhs->as_expression(); unsigned int i, matrix_columns = 1; - ir_variable *op_var[2]; + ir_variable *op[2]; if (!orig_expr) return visit_continue; @@ -340,7 +340,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) orig_assign->lhs->as_dereference_variable(); assert(lhs_deref); - ir_variable *result_var = lhs_deref->var; + ir_variable *result = lhs_deref->var; /* Store the expression operands in temps so we can use them * multiple times. @@ -348,12 +348,12 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) for (i = 0; i < orig_expr->get_num_operands(); i++) { ir_assignment *assign; - op_var[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, - "mat_op_to_vec", - ir_var_temporary); - base_ir->insert_before(op_var[i]); + op[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, + "mat_op_to_vec", + ir_var_temporary); + base_ir->insert_before(op[i]); - lhs_deref = new(mem_ctx) ir_dereference_variable(op_var[i]); + lhs_deref = new(mem_ctx) ir_dereference_variable(op[i]); assign = new(mem_ctx) ir_assignment(lhs_deref, orig_expr->operands[i], NULL); @@ -363,7 +363,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) /* OK, time to break down this matrix operation. */ switch (orig_expr->operation) { case ir_unop_neg: { - const unsigned mask = (1U << result_var->type->vector_elements) - 1; + const unsigned mask = (1U << result->type->vector_elements) - 1; /* Apply the operation to each column.*/ for (i = 0; i < matrix_columns; i++) { @@ -371,9 +371,9 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - get_column(op_var[0], i)); + get_column(op[0], i)); - column_assign = new(mem_ctx) ir_assignment(get_column(result_var, i), + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), column_expr, NULL, mask); @@ -386,7 +386,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) case ir_binop_sub: case ir_binop_div: case ir_binop_mod: { - const unsigned mask = (1U << result_var->type->vector_elements) - 1; + const unsigned mask = (1U << result->type->vector_elements) - 1; /* For most operations, the matrix version is just going * column-wise through and applying the operation to each column @@ -397,10 +397,10 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) ir_assignment *column_assign; column_expr = new(mem_ctx) ir_expression(orig_expr->operation, - get_column(op_var[0], i), - get_column(op_var[1], i)); + get_column(op[0], i), + get_column(op[1], i)); - column_assign = new(mem_ctx) ir_assignment(get_column(result_var, i), + column_assign = new(mem_ctx) ir_assignment(get_column(result, i), column_expr, NULL, mask); @@ -410,29 +410,29 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) break; } case ir_binop_mul: - if (op_var[0]->type->is_matrix()) { - if (op_var[1]->type->is_matrix()) { - do_mul_mat_mat(result_var, op_var[0], op_var[1]); - } else if (op_var[1]->type->is_vector()) { - do_mul_mat_vec(result_var, op_var[0], op_var[1]); + if (op[0]->type->is_matrix()) { + if (op[1]->type->is_matrix()) { + do_mul_mat_mat(result, op[0], op[1]); + } else if (op[1]->type->is_vector()) { + do_mul_mat_vec(result, op[0], op[1]); } else { - assert(op_var[1]->type->is_scalar()); - do_mul_mat_scalar(result_var, op_var[0], op_var[1]); + assert(op[1]->type->is_scalar()); + do_mul_mat_scalar(result, op[0], op[1]); } } else { - assert(op_var[1]->type->is_matrix()); - if (op_var[0]->type->is_vector()) { - do_mul_vec_mat(result_var, op_var[0], op_var[1]); + assert(op[1]->type->is_matrix()); + if (op[0]->type->is_vector()) { + do_mul_vec_mat(result, op[0], op[1]); } else { - assert(op_var[0]->type->is_scalar()); - do_mul_mat_scalar(result_var, op_var[1], op_var[0]); + assert(op[0]->type->is_scalar()); + do_mul_mat_scalar(result, op[1], op[0]); } } break; case ir_binop_all_equal: case ir_binop_any_nequal: - do_equal_mat_mat(result_var, op_var[1], op_var[0], + do_equal_mat_mat(result, op[1], op[0], (orig_expr->operation == ir_binop_all_equal)); break; -- cgit v1.2.3 From 8fad8637ef42ccd064a4f90b090d8096ab968e58 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 Jun 2011 12:08:56 -0700 Subject: glsl: Make lower_mat_op_to_vec track derefs, not variables. We were constrained to using temporaries because we were assuming variables all over. This simplifies things a bit. Reviewed-by: Kenneth Graunke --- src/glsl/lower_mat_op_to_vec.cpp | 127 +++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 71 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index 6d2bc0100f8..fe89802b086 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -45,19 +45,19 @@ public: ir_visitor_status visit_leave(ir_assignment *); - ir_dereference *get_column(ir_variable *var, int col); - ir_rvalue *get_element(ir_variable *var, int col, int row); - - void do_mul_mat_mat(ir_variable *result, - ir_variable *a, ir_variable *b); - void do_mul_mat_vec(ir_variable *result, - ir_variable *a, ir_variable *b); - void do_mul_vec_mat(ir_variable *result, - ir_variable *a, ir_variable *b); - void do_mul_mat_scalar(ir_variable *result, - ir_variable *a, ir_variable *b); - void do_equal_mat_mat(ir_variable *result, ir_variable *a, - ir_variable *b, bool test_equal); + ir_dereference *get_column(ir_dereference *val, int col); + ir_rvalue *get_element(ir_dereference *val, int col, int row); + + void do_mul_mat_mat(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_mat_vec(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_vec_mat(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_mul_mat_scalar(ir_dereference *result, + ir_dereference *a, ir_dereference *b); + void do_equal_mat_mat(ir_dereference *result, ir_dereference *a, + ir_dereference *b, bool test_equal); void *mem_ctx; bool made_progress; @@ -97,42 +97,30 @@ do_mat_op_to_vec(exec_list *instructions) } ir_rvalue * -ir_mat_op_to_vec_visitor::get_element(ir_variable *var, int col, int row) +ir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row) { - ir_dereference *deref; + val = get_column(val, col); - deref = new(mem_ctx) ir_dereference_variable(var); - - if (var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_array(var, - new(mem_ctx) ir_constant(col)); - } else { - assert(col == 0); - } - - return new(mem_ctx) ir_swizzle(deref, row, 0, 0, 0, 1); + return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1); } ir_dereference * -ir_mat_op_to_vec_visitor::get_column(ir_variable *var, int row) +ir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row) { - ir_dereference *deref; - - if (!var->type->is_matrix()) { - deref = new(mem_ctx) ir_dereference_variable(var); - } else { - deref = new(mem_ctx) ir_dereference_variable(var); - deref = new(mem_ctx) ir_dereference_array(deref, - new(mem_ctx) ir_constant(row)); + val = val->clone(mem_ctx, NULL); + + if (val->type->is_matrix()) { + val = new(mem_ctx) ir_dereference_array(val, + new(mem_ctx) ir_constant(row)); } - return deref; + return val; } void -ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, - ir_variable *a, - ir_variable *b) +ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int b_col, i; ir_assignment *assign; @@ -156,8 +144,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, mul_expr); } - ir_rvalue *result = get_column(result_var, b_col); - assign = new(mem_ctx) ir_assignment(result, + assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr, NULL); base_ir->insert_before(assign); @@ -165,9 +152,9 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var, } void -ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, - ir_variable *a, - ir_variable *b) +ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; ir_assignment *assign; @@ -188,7 +175,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr); } - ir_rvalue *result = new(mem_ctx) ir_dereference_variable(result_var); + result = result->clone(mem_ctx, NULL); assign = new(mem_ctx) ir_assignment(result, expr, NULL); @@ -196,9 +183,9 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var, } void -ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result, - ir_variable *a, - ir_variable *b) +ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; @@ -207,11 +194,11 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result, ir_expression *column_expr; ir_assignment *column_assign; - column_result = new(mem_ctx) ir_dereference_variable(result); + column_result = result->clone(mem_ctx, NULL); column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1); column_expr = new(mem_ctx) ir_expression(ir_binop_dot, - new(mem_ctx) ir_dereference_variable(a), + a->clone(mem_ctx, NULL), get_column(b, i)); column_assign = new(mem_ctx) ir_assignment(column_result, @@ -222,9 +209,9 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result, } void -ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result, - ir_variable *a, - ir_variable *b) +ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result, + ir_dereference *a, + ir_dereference *b) { int i; @@ -234,7 +221,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result, column_expr = new(mem_ctx) ir_expression(ir_binop_mul, get_column(a, i), - new(mem_ctx) ir_dereference_variable(b)); + b->clone(mem_ctx, NULL)); column_assign = new(mem_ctx) ir_assignment(get_column(result, i), column_expr, @@ -244,9 +231,9 @@ ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result, } void -ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, - ir_variable *a, - ir_variable *b, +ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result, + ir_dereference *a, + ir_dereference *b, bool test_equal) { /* This essentially implements the following GLSL: @@ -297,11 +284,8 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var, if (test_equal) any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any); - ir_rvalue *const result = - new(this->mem_ctx) ir_dereference_variable(result_var); - ir_assignment *const assign = - new(mem_ctx) ir_assignment(result, any, NULL); + new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any, NULL); base_ir->insert_before(assign); } @@ -324,7 +308,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) { ir_expression *orig_expr = orig_assign->rhs->as_expression(); unsigned int i, matrix_columns = 1; - ir_variable *op[2]; + ir_dereference *op[2]; if (!orig_expr) return visit_continue; @@ -336,11 +320,9 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) mem_ctx = ralloc_parent(orig_assign); - ir_dereference_variable *lhs_deref = + ir_dereference_variable *result = orig_assign->lhs->as_dereference_variable(); - assert(lhs_deref); - - ir_variable *result = lhs_deref->var; + assert(result); /* Store the expression operands in temps so we can use them * multiple times. @@ -348,13 +330,16 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) for (i = 0; i < orig_expr->get_num_operands(); i++) { ir_assignment *assign; - op[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, - "mat_op_to_vec", - ir_var_temporary); - base_ir->insert_before(op[i]); + ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, + "mat_op_to_vec", + ir_var_temporary); + base_ir->insert_before(var); - lhs_deref = new(mem_ctx) ir_dereference_variable(op[i]); - assign = new(mem_ctx) ir_assignment(lhs_deref, + /* Note that we use this dereference for the assignment. That means + * that others that want to use op[i] have to clone the deref. + */ + op[i] = new(mem_ctx) ir_dereference_variable(var); + assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i], NULL); base_ir->insert_before(assign); -- cgit v1.2.3 From 487dd96c2706aa352ed44637507dd7f38ac80306 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 Jun 2011 12:20:09 -0700 Subject: glsl: Avoid making a temporary for lower_mat_op_to_vec if not needed. Our copy propagation tends to be bad at handling the later array accesses of the matrix argument we moved to a temporary. Generally we don't need to move it to a temporary, though, so this avoids needing more copy propagation complexity. Reduces instruction count of some Unigine Tropics and Sanctuary fragment shaders that do operations on uniform matrix arrays by 5.9% on gen6. Reviewed-by: Kenneth Graunke --- src/glsl/lower_mat_op_to_vec.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/glsl') diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index fe89802b086..9d593f9dd0e 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -329,7 +329,18 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) */ for (i = 0; i < orig_expr->get_num_operands(); i++) { ir_assignment *assign; + ir_dereference *deref = orig_expr->operands[i]->as_dereference(); + /* Avoid making a temporary if we don't need to to avoid aliasing. */ + if (deref && + deref->variable_referenced() != result->variable_referenced()) { + op[i] = deref; + continue; + } + + /* Otherwise, store the operand in a temporary generally if it's + * not a dereference. + */ ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type, "mat_op_to_vec", ir_var_temporary); -- cgit v1.2.3 From e617a53a74cd27a322fd2dd05ff1c66c6437fde3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 Jun 2011 13:17:07 -0700 Subject: glsl: Allow ir_assignment() constructor to not specify condition. We almost never want to specify a condition, and when we do we're already thinking about it (because we're writing a lowering pass generating the condition), so a default argument should make the code more pleasant to read. NOTE: This is a candidate for the 7.11 branch (we want to be able to cherry-pick future code). Reviewed-by: Kenneth Graunke --- src/glsl/ir.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl') diff --git a/src/glsl/ir.h b/src/glsl/ir.h index a41984310b3..9d6ce7eaa20 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -682,7 +682,7 @@ public: class ir_assignment : public ir_instruction { public: - ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); + ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition = NULL); /** * Construct an assignment with an explicit write mask -- cgit v1.2.3 From 4f799e614264d2409fd32e3e3992405bb3fd924f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 24 Jun 2011 13:21:29 -0700 Subject: glsl: Use the default values of ir_assignment() in lower_mat_op_to_vec. Reviewed-by: Kenneth Graunke --- src/glsl/lower_mat_op_to_vec.cpp | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp index 9d593f9dd0e..a371afc14c2 100644 --- a/src/glsl/lower_mat_op_to_vec.cpp +++ b/src/glsl/lower_mat_op_to_vec.cpp @@ -144,9 +144,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result, mul_expr); } - assign = new(mem_ctx) ir_assignment(get_column(result, b_col), - expr, - NULL); + assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr); base_ir->insert_before(assign); } } @@ -176,9 +174,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result, } result = result->clone(mem_ctx, NULL); - assign = new(mem_ctx) ir_assignment(result, - expr, - NULL); + assign = new(mem_ctx) ir_assignment(result, expr); base_ir->insert_before(assign); } @@ -202,8 +198,7 @@ ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result, get_column(b, i)); column_assign = new(mem_ctx) ir_assignment(column_result, - column_expr, - NULL); + column_expr); base_ir->insert_before(column_assign); } } @@ -224,8 +219,7 @@ ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result, b->clone(mem_ctx, NULL)); column_assign = new(mem_ctx) ir_assignment(get_column(result, i), - column_expr, - NULL); + column_expr); base_ir->insert_before(column_assign); } } @@ -285,7 +279,7 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result, any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any); ir_assignment *const assign = - new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any, NULL); + new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any); base_ir->insert_before(assign); } @@ -350,17 +344,13 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) * that others that want to use op[i] have to clone the deref. */ op[i] = new(mem_ctx) ir_dereference_variable(var); - assign = new(mem_ctx) ir_assignment(op[i], - orig_expr->operands[i], - NULL); + assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i]); base_ir->insert_before(assign); } /* OK, time to break down this matrix operation. */ switch (orig_expr->operation) { case ir_unop_neg: { - const unsigned mask = (1U << result->type->vector_elements) - 1; - /* Apply the operation to each column.*/ for (i = 0; i < matrix_columns; i++) { ir_expression *column_expr; @@ -370,9 +360,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) get_column(op[0], i)); column_assign = new(mem_ctx) ir_assignment(get_column(result, i), - column_expr, - NULL, - mask); + column_expr); assert(column_assign->write_mask != 0); base_ir->insert_before(column_assign); } @@ -382,8 +370,6 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) case ir_binop_sub: case ir_binop_div: case ir_binop_mod: { - const unsigned mask = (1U << result->type->vector_elements) - 1; - /* For most operations, the matrix version is just going * column-wise through and applying the operation to each column * if available. @@ -397,9 +383,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign) get_column(op[1], i)); column_assign = new(mem_ctx) ir_assignment(get_column(result, i), - column_expr, - NULL, - mask); + column_expr); assert(column_assign->write_mask != 0); base_ir->insert_before(column_assign); } -- cgit v1.2.3 From 20ef96c7ff3f17fbf97e0452a37553249b2b005c Mon Sep 17 00:00:00 2001 From: Bryan Cain Date: Tue, 14 Jun 2011 23:34:11 -0700 Subject: glsl: Add ir_unop_i2u and ir_unop_u2i operations. These are necessary to handle int/uint constructor conversions. For example, the following code currently results in a type mismatch: int x = 7; uint y = uint(x); In particular, uint(x) still has type int. This commit simply adds the new operations; it does not generate them, nor does it add backend support for them. Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- src/glsl/ir.cpp | 8 ++++++++ src/glsl/ir.h | 2 ++ src/glsl/ir_constant_expression.cpp | 13 ++++++++++++- src/glsl/ir_validate.cpp | 8 ++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) (limited to 'src/glsl') diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index a3623b31e5d..95689dc10b0 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -272,6 +272,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2i: case ir_unop_b2i: + case ir_unop_u2i: this->type = glsl_type::get_instance(GLSL_TYPE_INT, op0->type->vector_elements, 1); break; @@ -289,6 +290,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) op0->type->vector_elements, 1); break; + case ir_unop_i2u: + this->type = glsl_type::get_instance(GLSL_TYPE_UINT, + op0->type->vector_elements, 1); + break; + case ir_unop_noise: this->type = glsl_type::float_type; break; @@ -419,6 +425,8 @@ static const char *const operator_strs[] = { "i2b", "b2i", "u2f", + "i2u", + "u2i", "any", "trunc", "ceil", diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 9d6ce7eaa20..42a3936976a 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -789,6 +789,8 @@ enum ir_expression_operation { ir_unop_i2b, /**< int-to-boolean conversion */ ir_unop_b2i, /**< Boolean-to-int conversion */ ir_unop_u2f, /**< Unsigned-to-float conversion. */ + ir_unop_i2u, /**< Integer-to-unsigned conversion. */ + ir_unop_u2i, /**< Unsigned-to-integer conversion. */ ir_unop_any, /** diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp index 2a308489656..f0299a2c4a0 100644 --- a/src/glsl/ir_constant_expression.cpp +++ b/src/glsl/ir_constant_expression.cpp @@ -166,7 +166,18 @@ ir_expression::constant_expression_value() data.b[c] = op[0]->value.u[c] ? true : false; } break; - + case ir_unop_u2i: + assert(op[0]->type->base_type == GLSL_TYPE_UINT); + for (unsigned c = 0; c < op[0]->type->components(); c++) { + data.i[c] = op[0]->value.u[c]; + } + break; + case ir_unop_i2u: + assert(op[0]->type->base_type == GLSL_TYPE_INT); + for (unsigned c = 0; c < op[0]->type->components(); c++) { + data.u[c] = op[0]->value.i[c]; + } + break; case ir_unop_any: assert(op[0]->type->is_boolean()); data.b[0] = false; diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 7b1c19d65aa..41ffdfdbcc7 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -280,6 +280,14 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); assert(ir->type->base_type == GLSL_TYPE_FLOAT); break; + case ir_unop_i2u: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); + assert(ir->type->base_type == GLSL_TYPE_UINT); + break; + case ir_unop_u2i: + assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); + assert(ir->type->base_type == GLSL_TYPE_INT); + break; case ir_unop_any: assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); -- cgit v1.2.3 From 3283e362e313f8a45fd6ee812efb737c0becc38c Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 14 Jun 2011 12:40:09 -0700 Subject: glsl: Revert "fix conversions from uint to bool and from..." Reverts commit f41e1db3273a31285360241c4342f0a403ee0b03 "fix conversions from uint to bool and from float/bool to uint" f2i, b2i, and b2i should not accept uint types. Use i2u and u2i. Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- src/glsl/ir_validate.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp index 41ffdfdbcc7..f3fceb2a57d 100644 --- a/src/glsl/ir_validate.cpp +++ b/src/glsl/ir_validate.cpp @@ -254,7 +254,7 @@ ir_validate::visit_leave(ir_expression *ir) case ir_unop_f2i: assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); - assert(ir->type->is_integer()); + assert(ir->type->base_type == GLSL_TYPE_INT); break; case ir_unop_i2f: assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); @@ -269,12 +269,12 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->type->base_type == GLSL_TYPE_FLOAT); break; case ir_unop_i2b: - assert(ir->operands[0]->type->is_integer()); + assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT); assert(ir->type->base_type == GLSL_TYPE_BOOL); break; case ir_unop_b2i: assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); - assert(ir->type->is_integer()); + assert(ir->type->base_type == GLSL_TYPE_INT); break; case ir_unop_u2f: assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT); -- cgit v1.2.3 From 6b1ba7ccef18232e5586fcda2ff75ef5bd05b57b Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 14 Jun 2011 23:23:49 -0700 Subject: glsl: Use i2u and u2i to implement constructor conversions. Inspired by a patch from Bryan Cain . Fixes piglit tests: - ctor-int-uint.vert - ctor-ivec4-uvec4.vert - ctor-uint-int.vert - ctor-uvec4-ivec4.vert Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- src/glsl/ast_function.cpp | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 3ba699ad971..60a2c617f70 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -271,17 +271,36 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) assert(a <= GLSL_TYPE_BOOL); assert(b <= GLSL_TYPE_BOOL); - if ((a == b) || (src->type->is_integer() && desired_type->is_integer())) + if (a == b) return src; switch (a) { case GLSL_TYPE_UINT: + switch (b) { + case GLSL_TYPE_INT: + result = new(ctx) ir_expression(ir_unop_i2u, src); + break; + case GLSL_TYPE_FLOAT: + result = new(ctx) ir_expression(ir_unop_i2u, + new(ctx) ir_expression(ir_unop_f2i, src)); + break; + case GLSL_TYPE_BOOL: + result = new(ctx) ir_expression(ir_unop_i2u, + new(ctx) ir_expression(ir_unop_b2i, src)); + break; + } + break; case GLSL_TYPE_INT: - if (b == GLSL_TYPE_FLOAT) - result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL); - else { - assert(b == GLSL_TYPE_BOOL); - result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL); + switch (b) { + case GLSL_TYPE_UINT: + result = new(ctx) ir_expression(ir_unop_u2i, src); + break; + case GLSL_TYPE_FLOAT: + result = new(ctx) ir_expression(ir_unop_f2i, src); + break; + case GLSL_TYPE_BOOL: + result = new(ctx) ir_expression(ir_unop_b2i, src); + break; } break; case GLSL_TYPE_FLOAT: @@ -300,6 +319,9 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) case GLSL_TYPE_BOOL: switch (b) { case GLSL_TYPE_UINT: + result = new(ctx) ir_expression(ir_unop_i2b, + new(ctx) ir_expression(ir_unop_u2i, src)); + break; case GLSL_TYPE_INT: result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL); break; @@ -311,6 +333,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) } assert(result != NULL); + assert(result->type == desired_type); /* Try constant folding; it may fold in the conversion we just added. */ ir_constant *const constant = result->constant_expression_value(); -- cgit v1.2.3 From 60eb63a855cb89962f2d5bb91e238ff2d1ab8702 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 14 Jun 2011 16:28:32 -0700 Subject: glsl: Find the "closest" signature when there are multiple matches. Previously, ir_function::matching_signature had a fatal bug: if a function had more than one non-exact match, it would simply return NULL. This occured, for example, when looking for max(uvec3, uvec3): - max(vec3, vec3) -> score 1 (found first) - max(ivec3, ivec3) -> score 1 (found second...used to return NULL here) - max(uvec3, uvec3) -> score 0 (exact match...the right answer) This did not occur for max(ivec3, ivec3) since the second match found was an exact match. The new behavior is to return a match with the lowest score. If there is an exact match, that will be returned. Otherwise, a match with the least number of implicit conversions is chosen. Fixes piglit tests max-uvec3.vert and glsl-inexact-overloads.shader_test. NOTE: This is a candidate for the 7.10 and 7.11 branches. Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- src/glsl/ir_function.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp index caee9296af9..ef8d4fcfcd4 100644 --- a/src/glsl/ir_function.cpp +++ b/src/glsl/ir_function.cpp @@ -165,6 +165,7 @@ ir_function_signature * ir_function::matching_signature(const exec_list *actual_parameters) { ir_function_signature *match = NULL; + int matched_score; foreach_iter(exec_list_iterator, iter, signatures) { ir_function_signature *const sig = @@ -173,14 +174,14 @@ ir_function::matching_signature(const exec_list *actual_parameters) const int score = parameter_lists_match(& sig->parameters, actual_parameters); + /* If we found an exact match, simply return it */ if (score == 0) return sig; - if (score > 0) { - if (match != NULL) - return NULL; - + /* If we found a match with fewer conversions, use that instead */ + if (score > 0 && (match == NULL || score < matched_score)) { match = sig; + matched_score = score; } } -- cgit v1.2.3 From 8eb975394478a5c1ebd2bd8a12b5eb61cef808a7 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 14 Jun 2011 22:21:41 -0700 Subject: glsl: Distinguish "type mismatch" error messages for modulus operator. Previously, it would simply say "type error" in three different cases: - The LHS is not an integer - The RHS is not an integer - The LHS and RHS have different base types (int vs. uint) Now the error messages state the specific problem. Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- src/glsl/ast_to_hir.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 35cb2067060..2e54e8c22d8 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -447,9 +447,17 @@ modulus_result_type(const struct glsl_type *type_a, * integer vectors. The operand types must both be signed or both be * unsigned." */ - if (!type_a->is_integer() || !type_b->is_integer() - || (type_a->base_type != type_b->base_type)) { - _mesa_glsl_error(loc, state, "type mismatch"); + if (!type_a->is_integer()) { + _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer."); + return glsl_type::error_type; + } + if (!type_b->is_integer()) { + _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer."); + return glsl_type::error_type; + } + if (type_a->base_type != type_b->base_type) { + _mesa_glsl_error(loc, state, + "operands of %% must have the same base type"); return glsl_type::error_type; } -- cgit v1.2.3 From ed92b912120394f3b19958effaa819d29bc6d059 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 14 Jun 2011 22:47:04 -0700 Subject: glsl: Fix DIV_TO_MUL_RCP lowering for uint result types. f2i results in an int/ivec; we need i2u to get a uint/uvec. Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- src/glsl/lower_instructions.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/glsl') diff --git a/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp index a5f61f213d0..94b8c4a6836 100644 --- a/src/glsl/lower_instructions.cpp +++ b/src/glsl/lower_instructions.cpp @@ -168,8 +168,13 @@ lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir) op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1); - ir->operation = ir_unop_f2i; - ir->operands[0] = op0; + if (ir->operands[1]->type->base_type == GLSL_TYPE_INT) { + ir->operation = ir_unop_f2i; + ir->operands[0] = op0; + } else { + ir->operation = ir_unop_i2u; + ir->operands[0] = new(ir) ir_expression(ir_unop_f2i, op0); + } ir->operands[1] = NULL; } -- cgit v1.2.3 From 578f6a9534ec6ea1ffc6638b98f0b5570a85a19d Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 14 Jun 2011 23:13:27 -0700 Subject: glsl: Don't use MOD_TO_FRACT lowering on GLSL 1.30's % operator. MOD_TO_FRACT was designed to lower the GLSL 1.20 mod() function, which operates on floating point values. However, we also use ir_binop_mod for GLSL 1.30's % operator, which operates on integers. For now, make MOD_TO_FRACT only apply to floating-point mod operations. In the future, we may want to add a lowering pass for integer-based mod. Signed-off-by: Kenneth Graunke Reviewed-by: Ian Romanick Reviewed-by: Eric Anholt --- src/glsl/lower_instructions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/glsl') diff --git a/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp index 94b8c4a6836..806f8639959 100644 --- a/src/glsl/lower_instructions.cpp +++ b/src/glsl/lower_instructions.cpp @@ -276,7 +276,7 @@ lower_instructions_visitor::visit_leave(ir_expression *ir) break; case ir_binop_mod: - if (lowering(MOD_TO_FRACT)) + if (lowering(MOD_TO_FRACT) && ir->type->is_float()) mod_to_fract(ir); break; -- cgit v1.2.3