Commit graph

160 commits

Author SHA1 Message Date
Rob Clark
183db3a645 glsl: move half<->float convertion to util
Needed in NIR too, so move out of mesa/main/imports.c

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Rob Clark <robclark@freedesktop.org>
2015-10-16 19:33:37 -04:00
Matt Turner
3c050222b0 mesa: Use _mesa_lroundevenf() in some more places. 2015-08-04 10:32:39 -07:00
Matt Turner
23bba717e1 glsl: Avoid double promotion. 2015-07-29 09:34:52 -07:00
Matt Turner
5c7fd67045 glsl: Remove MSVC implementations of copysign and isnormal.
Non-Gallium parts of Mesa require MSVC 2013 which provides these.
2015-07-29 09:34:51 -07:00
Matt Turner
5c71cf8531 glsl: Remove never used sin_reduced/cos_reduced.
These were added in commit f2616e56, presumably in preparation for
translating ARB vp/fp into GLSL IR. That never happened, and neither did
a lowering pass that actually generated these instructions.

Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-04-06 10:13:22 -07:00
Matt Turner
dd0d3a2c0f mesa: Replace _mesa_round_to_even() with _mesa_roundeven().
Eric's initial patch adding constant expression evaluation for
ir_unop_round_even used nearbyint. The open-coded _mesa_round_to_even
implementation came about without much explanation after a reviewer
asked whether nearbyint depended on the application not modifying the
rounding mode. Of course (as Eric commented) we rely on the application
not changing the rounding mode from its default (round-to-nearest) in
many other places, including the IROUND function used by
_mesa_round_to_even!

Worse, IROUND() is implemented using the trunc(x + 0.5) trick which
fails for x = nextafterf(0.5, 0.0).

Still worse, _mesa_round_to_even unexpectedly returns an int. I suspect
that could cause problems when rounding large integral values not
representable as an int in ir_constant_expression.cpp's
ir_unop_round_even evaluation. Its use of _mesa_round_to_even is clearly
broken for doubles (as noted during review).

The constant expression evaluation code for the packing built-in
functions also mistakenly assumed that _mesa_round_to_even returned a
float, as can be seen by the cast through a signed integer type to an
unsigned (since negative float -> unsigned conversions are undefined).

rint() and nearbyint() implement the round-half-to-even behavior we want
when the rounding mode is set to the default round-to-nearest. The only
difference between them is that nearbyint() raises the inexact
exception.

This patch implements _mesa_roundeven{f,}, a function similar to the
roundeven function added by a yet unimplemented technical specification
(ISO/IEC TS 18661-1:2014), with a small difference in behavior -- we
don't bother raising the inexact exception, which I don't think we care
about anyway.

At least recent Intel CPUs can quickly change a subset of the bits in
the x87 floating-point control register, but the exception mask bits are
not included. rint() does not need to change these bits, but nearbyint()
does (twice: save old, set new, and restore old) in order to raise the
inexact exception, which would incur some penalty.

Reviewed-by: Carl Worth <cworth@cworth.org>
2015-03-18 21:06:26 -07:00
Brian Paul
c16c719647 glsl: replace Elements() with ARRAY_SIZE()
Acked-by: Ilia Mirkin <imirkin@alum.mit.edu>
2015-03-02 08:55:30 -07:00
Dave Airlie
eeae6251be glsl/ir: Add builtin constant function support for doubles
Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
2015-02-19 00:28:34 -05:00
Alan Coopersmith
d602fbd861 Avoid fighting with Solaris headers over isnormal()
When compiling in C99 or C++11 modes, Solaris defines isnormal() as
a macro via <math.h>, which causes the function definition to become
too mangled to compile.

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Cc: "10.5" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
2015-02-17 18:16:33 -08:00
Abdiel Janulgue
4c0ccfc5b3 glsl: Add constant evaluation of ir_unop_saturate
v2: Use CLAMP macro (Ian Romanick)

Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2014-08-31 21:04:08 +03:00
Ilia Mirkin
f80c6847e9 glsl: add ARB_derivative control support
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2014-08-14 20:25:32 -04:00
Chris Forbes
1d5b06664f glsl: add new expression types for interpolateAt*
Will be used to implement interpolateAt*() from ARB_gpu_shader5

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
2014-07-12 11:20:00 +12:00
Matt Turner
4d78446d78 glsl: Use typed foreach_in_list instead of foreach_list.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2014-07-01 08:55:51 -07:00
Thomas Helland
8e1e68119c glsl: Remove unused include from ir_constant_expression.cpp
Found with IWYU. Compile-tested on my Ivy-bridge system.

Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Thomas Helland <thomashelland90@gmail.com>
2014-06-10 13:05:51 -07:00
Ian Romanick
c4cec40883 glsl: Clean up "unused parameter" warnings
../../src/glsl/ir_constant_expression.cpp:486:1: warning: unused parameter 'variable_context' [-Wunused-parameter]
../../src/glsl/ir_constant_expression.cpp:1633:1: warning: unused parameter 'variable_context' [-Wunused-parameter]
../../src/glsl/ir_constant_expression.cpp:1752:1: warning: unused parameter 'variable_context' [-Wunused-parameter]
../../src/glsl/ir_constant_expression.cpp:1761:1: warning: unused parameter 'variable_context' [-Wunused-parameter]
../../src/glsl/ir_constant_expression.cpp:1769:1: warning: unused parameter 'variable_context' [-Wunused-parameter]

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
2014-03-25 12:09:36 -07:00
Ian Romanick
f3ab987b70 glsl: Minor clean ups in constant_referenced
These could probably be squashed into one of the previous commits.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
2014-03-25 12:09:36 -07:00
Ian Romanick
6429d6276d glsl: Remove ir_dereference::constant_referenced
All of the functionality is implemented in a private function in the one
file where it is used.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
2014-03-25 12:09:36 -07:00
Ian Romanick
bb0d6db974 glsl: Fold implementation of ir_dereference_array::constant_referenced into wrapper
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
2014-03-25 12:09:36 -07:00
Ian Romanick
35bf94f901 glsl: Fold implementation of ir_dereference_record::constant_referenced into wrapper
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
2014-03-25 12:09:36 -07:00
Ian Romanick
b66319b006 glsl: Fold implementation of ir_dereference_variable::constant_referenced into wrapper
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
2014-03-25 12:09:36 -07:00
Ian Romanick
14f0faacb6 glsl: Add wrapper function that calls ir_dereference::constant_referenced
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
2014-03-25 12:09:36 -07:00
Ian Romanick
c11c7e4f01 glsl: Group all of the constant_referenced functions together
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
2014-03-25 12:09:36 -07:00
Matt Turner
3ea64f9093 glsl: Add constant evaluation of ir_binop_bfm.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2014-01-27 21:15:35 -08:00
Thomas Sondergaard
067ad6e53e mesa: Fix compile error with MSVC 2013
This fixes the following compile error:
src\glsl\ir_constant_expression.cpp(1405) : error C2666: 'copysign' : 3
overloads have similar conversions

Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Brian Paul <brianp@vmware.com>
2014-01-08 17:33:06 -07:00
Tapani Pälli
33ee2c67c0 glsl: move variables in to ir_variable::data, part I
This patch moves following bitfields in to the data structure:

used, assigned, how_declared, mode, interpolation,
origin_upper_left, pixel_center_integer

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-12-12 17:28:08 +02:00
Vinson Lee
1349766612 glsl: Define isnormal for Oracle Solaris Studio.
This patch fixes this Oracle Solaris Studio build error.

"../../src/glsl/ir_constant_expression.cpp", line 1398: Error: The function "isnormal" must have a prototype.

Signed-off-by: Vinson Lee <vlee@freedesktop.org>
2013-10-04 15:37:33 -07:00
Vinson Lee
6d29db715b glsl: Define isnormal and copysign for MSVC to fix build.
This patch fixes these MSVC build errors.

ir_constant_expression.cpp
src\glsl\ir_constant_expression.cpp(564) : warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
src\glsl\ir_constant_expression.cpp(1384) : error C3861: 'isnormal': identifier not found
src\glsl\ir_constant_expression.cpp(1385) : error C3861: 'copysign': identifier not found

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=69541
Signed-off-by: Vinson Lee <vlee@freedesktop.org>
Acked-by: Matt Turner <mattst88@gmail.com>
2013-09-22 16:11:36 -07:00
Matt Turner
b2ab840130 glsl: Add support for ldexp.
v2: Drop frexp. Rebase on builtins rewrite.
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-09-17 16:59:05 -07:00
Matt Turner
7aaa38728f glsl: Add conditional-select IR.
It's a ?: that operates per-component on vectors. Will be used in
upcoming lowering pass for ldexp and the implementation of frexp.

 csel(selector, a, b):
   per-component result = selector ? a : b

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-09-09 15:01:08 -07:00
Kenneth Graunke
4b0bac0dce glsl: Convert ir_function_signature::is_builtin to a method.
A signature is a built-in if and only if builtin_info != NULL, so we
don't actually need a separate flag bit.  Making a boolean-valued
method allows existing code to ask the same question while not worrying
about the internal representation.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-09-09 11:46:51 -07:00
Matt Turner
d55c543c36 glsl: Add support for new fma built-in in ARB_gpu_shader5.
v2: Add constant folding support.
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-08-27 15:03:30 -07:00
Ian Romanick
dafd6918f3 glsl: Add ir_triop_vector_insert
The new opcode is used to generate a new vector with a single field from
the source vector replaced.  This will eventually replace
ir_dereference_array of vectors in the LHS of assignments.

v2: Convert tabs to spaces.  Suggested by Eric.

v3: Add constant expression handling for ir_triop_vector_insert.  This
prevents the constant matrix inversion tests from regressing.  Duh.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-05-13 12:05:18 -07:00
Ian Romanick
f274a2ca87 glsl: Add ir_binop_vector_extract
The new opcode is used to get a single field from a vector.  The field
index may not be constant.  This will eventually replace
ir_dereference_array of vectors.  This is similar to the extractelement
instruction in LLVM IR.

http://llvm.org/docs/LangRef.html#extractelement-instruction

v2: Convert tabs to spaces.  Suggested by Eric.

v3: Add array index range checking to ir_binop_vector_extract constant
expression handling.  Suggested by Ken.

v4: Use CLAMP instead of MIN2(MAX2()).  Suggested by Ken.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2013-05-13 12:05:18 -07:00
Matt Turner
9c04b8c28c glsl: Add constant evaluation of bit built-ins.
v2: Order bits from LSB end (31 - count) for ir_unop_find_msb.
v3: Add ir_triop_bitfield_extract as an exception to the op[0]->type ==
    op[1]->type assertion in ir_constant_expression.cpp.

Reviewed-by: Chris Forbes <chrisf@ijw.co.nz> [v2]
2013-05-06 10:17:13 -07:00
Paul Berry
7d4f1e6467 glsl: Fix array indexing when constant folding built-in functions.
Mesa constant-folds built-in functions by using a miniature GLSL
interpreter (see
ir_function_signature::constant_expression_evaluate_expression_list()).
This interpreter had a bug in its handling of array indexing, which
caused expressions like "m[i][j]" (where m is a matrix) to be handled
incorrectly.  Specifically, it incorrectly treated j as indexing into
the whole matrix (rather than indexing just into the vector m[i]); as
a result the offset computed for m[i] was lost and m[i][j] was treated
as m[j][0].

Fixes piglit tests inverse-mat[234].{vert,frag}.

NOTE: This is a candidate for the 9.1 and 9.0 branches.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57436
2013-04-02 12:24:08 -07:00
Kenneth Graunke
93066ce129 glsl: Convert mix() to use a new ir_triop_lrp opcode.
Many GPUs have an instruction to do linear interpolation which is more
efficient than simply performing the algebra necessary (two multiplies,
an add, and a subtract).

Pattern matching or peepholing this is more desirable, but can be
tricky.  By using an opcode, we can at least make shaders which use the
mix() built-in get the more efficient behavior.

Currently, all consumers lower ir_triop_lrp.  Subsequent patches will
actually generate different code.

v2 [mattst88]:
   - Add LRP_TO_ARITH flag to ir_to_mesa.cpp. Will be removed in a
     subsequent patch and ir_triop_lrp translated directly.
v3 [mattst88]:
   - Move changes from the next patch to opt_algebraic.cpp to accept
     3-src operations.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
2013-02-28 13:18:59 -08:00
Matt Turner
1ef674f215 glsl: Evaluate constant pack/unpack 4x8 expressions
That is, evaluate constant expressions for the following functions:
  packSnorm4x8, unpackSnorm4x8
  packUnorm4x8, unpackUnorm4x8

Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
2013-01-25 14:10:23 -08:00
Chad Versace
542c7a3022 glsl: Evaluate constant GLSL ES 3.00 pack/unpack expressions (v3)
That is, evaluate constant expressions of the following functions:
  packSnorm2x16  unpackSnorm2x16
  packUnorm2x16  unpackUnorm2x16
  packHalf2x16   unpackHalf2x16

v2: Reuse _mesa_pack_float_to_half and its inverse to evaluate
    pack/unpackHalf2x16. [for idr]
v3: Whitespace fixes. [for mattst88]
    Don't cast neg floats directly to uint16; use an intermediate cast to
    int16. [for paul]

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> (v2)
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Reviewed-by: Matt Tuner <mattst88@gmail.com>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2013-01-24 21:24:10 -08:00
Chad Versace
eac030e38e mesa,glsl: Move round_to_even() from glsl to mesa/main (v2)
Move round_to_even's definition to mesa/main so that _mesa_float_to_half()
can use it in order to eliminate rounding bias.

In additon to moving the fuction definition, prefix its name with "_mesa",
just as all other functions in mesa/main are prefixed.

v2: Fix Android build.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2013-01-24 21:24:07 -08:00
Paul Berry
613a8170ae glsl: Add support for ir_unop_f2u to constant folding.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2012-06-15 08:58:55 -07:00
Marcin Slusarz
ea055e19c2 glsl: fix deref_hash memory leak in constant_expression_value
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2012-06-08 21:00:40 +02:00
Olivier Galibert
abe9767553 glsl: Bitwise conversion operator support in ir_constant_expression.
A "test_out = floatBitsToUint(-1.0);" fired through the GLSL compiler
gives a correct "(assign (x) (var_ref test_out)
(constant uint (3212836864)))"

Signed-off-by: Olivier Galibert <galibert@pobox.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2012-06-07 00:06:18 -07:00
Olivier Galibert
363c14ae0c glsl: Change built-in constant expression evaluation to run the IR.
This removes code duplication with
ir_expression::constant_expression_value and builtins/ir/*.

Signed-off-by: Olivier Galibert <galibert@pobox.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2012-05-08 12:55:52 -07:00
Olivier Galibert
a270e86d38 glsl: Add a constant_referenced method to ir_dereference*
The method is used to get a reference to an ir_constant * within the
context of evaluating an assignment when calculating a
constant_expression_value.

Signed-off-by: Olivier Galibert <galibert@pobox.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net> [v1]
2012-05-08 12:55:47 -07:00
Olivier Galibert
6e4852a3a5 glsl: Add a variable context to constant_expression_value().
Signed-off-by: Olivier Galibert <galibert@pobox.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net> [v1]
2012-05-08 12:55:46 -07:00
Kenneth Graunke
f72e9b2041 glsl: Fix broken constant expression handling for <, <=, >, and >=.
We were looping over all the vector components, but only dealing with
the first one.  This was masked by the fact that constant expression
handling on built-ins went through custom code for the lessThan()
/function/ rather than the ir_binop_less expression operator.

NOTE: This is a candidate for all release branches.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Signed-off-by: Olivier Galibert <galibert@pobox.com>
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
2012-05-08 12:28:44 -07:00
Kenneth Graunke
d884f60861 glsl: Convert ir_call to be a statement rather than a value.
Aside from ir_call, our IR is cleanly split into two classes:
- Statements (typeless; used for side effects, control flow)
- Values (deeply nestable, pure, typed expression trees)

Unfortunately, ir_call confused all this:
- For void functions, we placed ir_call directly in the instruction
  stream, treating it as an untyped statement.  Yet, it was a subclass
  of ir_rvalue, and no other ir_rvalue could be used in this way.
- For functions with a return value, ir_call could be placed in
  arbitrary expression trees.  While this fit naturally with the source
  language, it meant that expressions might not be pure, making it
  difficult to transform and optimize them.  To combat this, we always
  emitted ir_call directly in the RHS of an ir_assignment, only using
  a temporary variable in expression trees.  Many passes relied on this
  assumption; the acos and atan built-ins violated it.

This patch makes ir_call a statement (ir_instruction) rather than a
value (ir_rvalue).  Non-void calls now take a ir_dereference of a
variable, and store the return value there---effectively a call and
assignment rolled into one.  They cannot be embedded in expressions.

All expression trees are now pure, without exception.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2012-04-02 14:15:41 -07:00
Kenneth Graunke
d0fa0cb52c glsl: Move constant expression handling from calls to signatures.
When translating a call from AST to HIR, we need to decide whether it
can be evaluated to a constant before emitting any code (namely, the
temporary declaration, assignment, and call.)

Soon, ir_call will become a statement taking a dereference of where to
store the return value, rather than an rvalue to be used on the RHS of
an assignment.  It will be more convenient to try evaluation before
creating a call.  ir_function_signature seems like a reasonable place.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2012-04-02 14:15:36 -07:00
Kenneth Graunke
807e967c61 glsl: Use ir_rvalue to represent generic error_type values.
Currently, ir_call can be used as either a statement (for void
functions) or a value (for non-void functions).  This is rather awkward,
as it's the only class that can be used in both forms.

A number of places use ir_call::get_error_instruction() to construct a
generic value of error_type.  If ir_call is to become a statement, it
can no longer serve this purpose.

Unfortunately, none of our classes are particularly well suited for
this, and creating a new one would be rather aggrandizing.  So, this
patch introduces ir_rvalue::error_value(), a static method that creates
an instance of the base class, ir_rvalue.  This has the nice property
that you can't accidentally try and access uninitialized fields (as it
doesn't have any).  The downside is that the base class is no longer
abstract.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2012-04-02 14:15:34 -07:00
Kenneth Graunke
a17a78a212 glsl: Handle constant expressions involving ir_binop_equal/nequal.
Constant expressions which called GLSL's equal() and notEqual()
built-ins on bvecs would hit an assertion failure; we simply forgot to
implement them for booleans.

NOTE: This is a candidate for stable release branches.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Chad Versace <chad.versace@linux.intel.com>
2011-11-10 22:51:20 -08:00