Commit Graph

100 Commits

Author SHA1 Message Date
John Stiles
ae5984082b Optimize SkVM selects.
The expression `!x ? y : z` can be optimized to `x ? z : y`, saving a
bit-not. SkVM now supports this optimization.

Change-Id: I06a0d2a716947de1021ba66b054b92e25568c641
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/524226
Reviewed-by: Arman Uguray <armansito@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2022-03-24 21:17:41 +00:00
John Stiles
059d34594e Optimize SkVM bit-clears.
SkVM has a `bit_clear` opcode dedicated to the operation `x & ~y`, but
the optimizer was not smart enough to combine a bit-and with a bit-not
and replace it with a bit-clear. Now, it can.

Change-Id: Ida5345c3def0a4bf7afa08bb7f7835e1e2e37677
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/524225
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Arman Uguray <armansito@google.com>
2022-03-24 21:04:23 +00:00
John Stiles
8318cc9928 Update opcode canonicalization logic in SkVM.
Previously, our ID canonicalization was simply "lower ID numbers before
higher ID numbers" and was done separately at every opcode by taking
the min and max of (x.id, y.id).

Now, this logic is factored out into a helper function
`canonicalizeIdOrder` and has two rules:
- Immediate values go last; that is, "x + 1" instead of "1 + x".
- If both/neither are immediate, lower IDs before higher IDs (as
  before)

This change lets us remove a lot of simplification logic. We no longer
need to check for both `x + 0` and `0 + x` when removing no-op
arithmetic; now we can be certain that the immediate will always come
last, so just checking for `x + 0` is sufficient.

Change-Id: I66cc5c23bba414041c0bc556521d3db57fac504d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/524222
Reviewed-by: Arman Uguray <armansito@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2022-03-24 19:14:51 +00:00
John Stiles
b8cee7dab3 Reject operators =, ==, and != on void types.
The fuzzer discovered that we allow == on void types (confusing the SkVM
backend).

Change-Id: Ia9494642faf67f3f86e3a365807be8bd4a7062e4
Bug: skia:13026
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/516796
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2022-03-07 14:10:29 +00:00
John Stiles
1c2b4492b8 Only run vector-folding logic on vectors.
Previously, we would take the vector-folding path for all types. This
didn't cause any problem for scalars, but failed for "zero-size" types
like void. It isn't valid to compare zero-size values, but we currently
don't reject such code (see skia:13026), and the fuzzer noticed this.
It's safest to only run the vector-folding code when we actually have
multiple slots that need to be folded into one result.

Change-Id: I0bc88043d9a4aeea38ae24dc1a6d1a7430d3d7b0
Bug: oss-fuzz:45279, skia:13026
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/516676
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2022-03-07 13:58:17 +00:00
John Stiles
7b40626ca9 Fix debugger return-value display with repeated function calls.
The slot-assignment logic has been changed to associate slots with
function calls, instead of function definitions. In our test case, you
can now see that the calls to `get` are now mapped to $15, $17 and $18.
This change also jiggles some existing tests and improves their
register allocation slightly (!).

One minor hitch here is that there's no FunctionCall node associated
with main() (it's never explicitly called). However, our slot map key
can be any IRNode, and we know main() can't be called by anyone else,
so it's harmless to use the function definition as the key in this case.
(This entry could probably stay out the map entirely if it made a
difference, but I don't think it matters.)

Change-Id: I68a6ff24cbd3a2db77f24126502bd3d11e8c0962
Bug: skia:13011
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/514578
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2022-03-03 20:55:25 +00:00
John Stiles
d9f9f1813c Add test demonstrating issue with function calls.
If a function is called multiple times on one line, stepping over that
line does not show all of the function-call results. It only shows the
last result.

e.g. in this example, I have just stepped over the first line which
calls "get" three times. We should see three results, but we only see
one: http://screen/3WfJoZWm77cSexM

In this test you can see that all three calls to `get` are assigned to
the same slot, $15.

Change-Id: Id0c486ef349a1e527001efbcee2ed2b836f56e83
Bug: skia:13011
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/514577
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2022-03-03 20:55:25 +00:00
John Stiles
60c5837632 Fix Housekeeper-PerCommit-CheckGeneratedFiles.
I added a comment and didn't rebuild; this shifted line numbers around,
which is reflected in the debug trace opcodes.

Change-Id: I1b8e00ff65557a03483e8d7ff0c4dbec9852866f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/514777
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Commit-Queue: Kevin Lubick <kjlubick@google.com>
2022-03-02 16:42:10 +00:00
John Stiles
e11a14d17f Add workaround for LLVM crash in macOS 12 on Intel or M1.
The `break_loop` test causes LLVM to get confused and crash when
compiled on some GPUs. The crash goes away if we pass a literal 5
instead of a 5 that is computed at runtime. This also results in a
simpler test for SkVM, for better or worse, but we still have
coverage for dynamic loop exits in other tests.

LLVM crash: https://paste.googleplex.com/4718583155261440
Dangerous shader: https://paste.googleplex.com/4776089520963584

Change-Id: Ic6cbd55a36d2de58e5dd3459d4dfd74acdbc9f91
Bug: skia:13005
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/514538
Reviewed-by: Arman Uguray <armansito@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2022-03-02 15:20:10 +00:00
John Stiles
1542db1a9b Add a test runtime effect for child effects.
I wasn't able to find any other test which exercised child color-filters
or child blenders. (SampleWithExplicitCoord evaluates from a shader.)

Change-Id: I58ecee3beca2d3dc11ded5de0eea031e1d7c3e1e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/507922
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Arman Uguray <armansito@google.com>
Commit-Queue: Arman Uguray <armansito@google.com>
2022-02-12 01:06:57 +00:00
John Stiles
f4103618ff Report an error if an out param is never written to.
GLSL ES2 behavior is explicitly undefined if an out-param is never
written to: "If a function does not write to an out parameter, the value
of the actual parameter is undefined when the function returns."

We do see divergence here in practice: SkVM's behavior (the parameter is
left alone) differs from my GPU's behavior (the parameter is zeroed
out).

SkSL will now report an error if an out parameter is never assigned-to.
There is no control flow analysis performed, so we will not report
cases where the out parameter is assigned-to on some paths but not
others. (Technically the return-on-all-paths logic could be adapted
for this, but it would be a fair amount of work.)

Structs are currently exempt from the rule because custom mesh
specifications require an `out` parameter for a Varyings struct, even if
your mesh program doesn't need Varyings.

Bug: skia:12867
Change-Id: Ie828d3ce91c2c67e008ae304fdb163ffa88d744c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/500440
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2022-01-26 21:42:13 +00:00
Ethan Nicholas
f393067c37 Made SkSL type aliases into first-class objects
Previously, type aliases ('vec2') were just an additional name which
could be used to refer to a type ('float2'). This was simple and worked,
except that error messages would be wrong - any type-related error
message would refer to the type as 'float2' rather than the 'vec2' that
the user actually typed.

This CL adds an AliasType class so that we can track which name was
used to refer to an aliased type and report messages using the correct
type name.

Bug: skia:12737

Change-Id: I40e234239ab47557033e0695e4fbbd5f01da354e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/490256
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
2022-01-05 16:20:19 +00:00
John Stiles
71f7880bb6 Emit trace_scope ops from SkVM code generation.
These will give the debugger enough information to discard variables as
they fall out of scope.

Change-Id: Ia400e82a3ca9cf0a51a72d819f897d346979226c
Bug: skia:12741
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/484556
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-12-15 01:05:34 +00:00
John Stiles
b1a97caf71 Revert "Trace function return values after function-exit."
This reverts commit 85cc1bece7.

Reason for revert: ends up not being useful after all

Original change's description:
> Trace function return values after function-exit.
>
> This will allow function return values to be easily seen when stepping
> "over." This has the unexpected side benefit of generating slightly
> fewer ops when a function has unoptimizable conditional returns.
>
> Change-Id: I48d23de635d3caaddff91aa595593d0371dfcdcb
> Bug: skia:12708
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/481076
> Reviewed-by: Brian Osman <brianosman@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>
> Auto-Submit: John Stiles <johnstiles@google.com>

Bug: skia:12708
Change-Id: I61ebb175b60d2060f6ad21b170238b37557b80be
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/482458
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-12-10 18:06:04 +00:00
John Stiles
83b5237b53 Fix assertion when debug-tracing a void-return function.
The debug-slot code didn't expect to encounter a void type.

Change-Id: Ied452b51e1cf90a0c0bc24770f82e711105b8e82
Bug: skia:12708
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/482461
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-12-10 14:39:05 +00:00
John Stiles
3856a5854e Revert "Add SkVM op trace_done to indicate completion of debug tracing."
This reverts commit 062652067b.

Reason for revert: design change removes need for this op

Original change's description:
> Add SkVM op `trace_done` to indicate completion of debug tracing.
>
> This op can be used to invoke a callback function and dump the log to
> disk when it is ready. SkRuntimeEffect doesn't have any other viable
> mechanisms for detecting that a paint has completed, AFAIK. We can
> wait for ~SkRTShader to occur, but there's no guarantee that this will
> happen quickly, and the SkPaint with the SkRTShader shader can be reused
> over and over again.
>
> Unlike other trace ops, this only needs a trace mask, not an execution
> mask (we are unconditionally done at the end of main).
>
> Change-Id: I6f7ee41f2005b65940d36dee892279d4f245509f
> Bug: skia:12708
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/479876
> Auto-Submit: John Stiles <johnstiles@google.com>
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>

Bug: skia:12708
Change-Id: Ic4c4f5dd72541195f07ca32035267a20a82536e7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/481577
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-12-08 17:49:56 +00:00
John Stiles
85cc1bece7 Trace function return values after function-exit.
This will allow function return values to be easily seen when stepping
"over." This has the unexpected side benefit of generating slightly
fewer ops when a function has unoptimizable conditional returns.

Change-Id: I48d23de635d3caaddff91aa595593d0371dfcdcb
Bug: skia:12708
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/481076
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-12-07 16:32:44 +00:00
Julia Lavrova
4388f16262 Fixing comparison for structs and arrays
Recursive comparison with tests

Bug: skia:12642
Change-Id: I344812a26f9af7b8a904c6faf6319df86ce57d03
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/472997
Commit-Queue: Julia Lavrova <jlavrova@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2021-12-06 20:46:41 +00:00
John Stiles
062652067b Add SkVM op trace_done to indicate completion of debug tracing.
This op can be used to invoke a callback function and dump the log to
disk when it is ready. SkRuntimeEffect doesn't have any other viable
mechanisms for detecting that a paint has completed, AFAIK. We can
wait for ~SkRTShader to occur, but there's no guarantee that this will
happen quickly, and the SkPaint with the SkRTShader shader can be reused
over and over again.

Unlike other trace ops, this only needs a trace mask, not an execution
mask (we are unconditionally done at the end of main).

Change-Id: I6f7ee41f2005b65940d36dee892279d4f245509f
Bug: skia:12708
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/479876
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-12-06 18:44:27 +00:00
Julia Lavrova
94f726ae62 Adding test files demonstrating type confusion for arrays/structs.
Change-Id: Iacd924471971c3c551648f75c1ecf0f1bfd3ed07
Bug: skia:12642
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/479061
Commit-Queue: Julia Lavrova <jlavrova@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2021-12-03 20:54:36 +00:00
John Stiles
d4713ad528 Move trace hooks into the skvm::Builder.
I ran into a snag while trying to hook up SkRuntimeEffect with debug
tracing. Runtime effects only have access to a skvm::Builder, and are
never exposed to the full skvm::Program. SkVMBlitter is responsible for
assembling the full skvm::Program, but is oblivious to runtime effects
and nested skvm sub-programs. Additionally, multiple runtime effects can
(and often do) coexist within a paint.

This CL changes how debug traces are enabled. skvm::Program no longer
has a `attachDebugTrace` method. Instead, this method lives on the
skvm::Builder. Calling `attachDebugTrace` generates a "trace-hook ID"
(which is actually an index into a vector of TraceHook pointers).
Every trace opcode now includes this trace hook ID. When the Builder
assembles a final Program, it copies the TraceHooks into the Program.
The skvm interpreter uses the trace hook ID on the op to dispatch a
trace command to its associated TraceHook.

From a user perspective, this doesn't change very much, but it does
mean that the SkVM Code Generator now supplies a TraceHook for us
(since it adds trace ops to the Builder and needs to know the proper
trace-hook ID).

Change-Id: I8bd5fea24f477f81470fae8ba41be45f76949407
Bug: skia:12708
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/479597
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-12-03 20:09:22 +00:00
John Stiles
2756b0ee02 Reduce the number of extra bit_and ops caused by SkVM traces.
Previously, the trace opcodes took a single mask argument, which was
computed as `execution mask & trace mask`. This led to extra bit_ands in
the output, as this value would be need to be recalculated every time
the execution mask changed.

To reduce this cost on program size, the trace ops now take two mask
arguments and require that both must be true. We have four register
slots at our disposal in an Op, which is more than we need, so this
doesn't really cost us anything.

(As an extra minor optimization, if one of the masks is "always-on", we
optimize it away. This avoids burning a register just to hold a ~0
immediate value.)

Change-Id: I9eb71292a1983e71b03c7ac842534beb3d6bbf17
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/478456
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-12-02 18:15:34 +00:00
John Stiles
dfe33f49f5 Add a setting to disable SkVM variable traces.
This will allow the visualizer to see line-number information without
incurring the code bloat caused by trace_var.

For reference, Commutative.skvm with no debug traces:
https://osscs.corp.google.com/skia/skia/+/main:tests/sksl/runtime/Commutative.skvm;drc=c809e5ba9fc9bc67291d088c448ed0057371b760

Change-Id: If98b5e102571d7fe06a1653d199e3ae035b3cb78
Bug: skia:12692
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/478417
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Julia Lavrova <jlavrova@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-12-01 17:25:59 +00:00
John Stiles
030f8260a7 Add debug traces to an existing test.
This demonstrates how much additional non-trace code can be generated
when debug traces are turned on. A followup CL adds a setting to disable
`trace_var`, which eliminates a significant percentage of the additional
ops (at the cost of removing valuable debug info).

Change-Id: I238e28e6f6531f1dbccfef8f1dcd24a1e8481669
Bug: skia:12692
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/478416
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Julia Lavrova <jlavrova@google.com>
2021-12-01 17:25:59 +00:00
John Stiles
5588bdd72d Put function return values in a slot.
This shouldn't change code generation when debug traces are disabled.
When they are enabled, we now get trace_var opcodes emitted for every
return statement. Internally, this required a fair amount of refactoring
around how return values are passed around, but it should all be
functionally equivalent.

Change-Id: Ieb9d9c75399109186f905e0499d8fe6e2fc2067c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/477981
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-30 19:25:31 +00:00
John Stiles
f57140768e Allow setting a trace coordinate without a skvm::Builder.
SkRuntimeEffect users will be insulated from skvm and the Builder, so
they won't be able to make an skvm::Coord directly. Replace this with
an SkIPoint, and do the conversion inside the SkVM code generator.

This also removes the requirement of assigning a trace coordinate; if
no trace coordinate is set, (0, 0) will be used.

Change-Id: I97be025d0ea146a86655cc3cdb76726f3bbc2324
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/474556
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-29 21:47:05 +00:00
John Stiles
eeb5b224c4 Separate enter and exit into two opcodes.
Reusing the same opcode for enter and exit didn't have any real upside,
and forced us to deal with a fake immediate-value.

Change-Id: I35cab4d196f55b6f5e3040074c731b298720d62b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/477157
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-11-29 15:55:58 +00:00
Brian Osman
4fa40eb741 Revert "Update some skvm test outputs"
This reverts commit b1f450bb2b.

Reason for revert: Hmm, bot disagrees.

Original change's description:
> Update some skvm test outputs
>
> Not sure how these were wrong in the repo for so long - these all should
> have changed like this when the optimization of commutative operations
> landed: reviews.skia.org/473239
>
> Change-Id: I3035d4f29c208096f83184b4393023666e10ab92
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/476316
> Auto-Submit: Brian Osman <brianosman@google.com>
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>

Change-Id: I9dc808927c73a979f4cde5c7035b109d8db808f6
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/476397
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-11-24 19:18:09 +00:00
Brian Osman
b1f450bb2b Update some skvm test outputs
Not sure how these were wrong in the repo for so long - these all should
have changed like this when the optimization of commutative operations
landed: reviews.skia.org/473239

Change-Id: I3035d4f29c208096f83184b4393023666e10ab92
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/476316
Auto-Submit: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-11-24 16:45:39 +00:00
John Stiles
fb0fa24e31 Remove VarType from trace_var opcode.
This is redundant information now that we have SkVMSlotInfo.

Change-Id: Ia05b1eaa722023e719042c83255708aa9debed61
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/473777
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-20 01:52:40 +00:00
John Stiles
217347528b Improve redundant trace_var elimination.
Previously, we would avoid emitting redundant trace_vars by checking to
see if the slot is being assigned to the exact same Var.ID. However,
this had the potential to eliminate useful trace_vars:

- At the start of execution, slots all contain 0. Code which explicitly
  assigned a zero into a slot would not be shown in a trace. (So things
  like `color = half4(0,1,0,1)` would only emit traces for color.ga.)
- A function call's parameter slots are reused every time it is called,
  so calling a function twice would only emit traces for the parameters
  that aren't the same Val.ID as the previous call.
- A VarDeclaration inside a loop reuses its slot each time through the
  loop, even though conceptually it's a "new" variable.

We now track a slot's "written-to" status. At the start of execution,
no slots have been "written-to". These slots will always emit a
trace_var opcode (fixing the first issue). Also, issuing a function
call or declaring a variable will reset the "written-to" status of the
associated slots (fixing the second and third issues).

When the debugger is not in use, the written-to field is unused.

Change-Id: I482a86cb6e90d0f85dd2a161e984f212782a7b4d
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/473776
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-18 22:18:42 +00:00
John Stiles
c809e5ba9f Optimize commutative operations in SkVM.
We now canonicalize commutative operations by ordering their value IDs.
The lower-numbered value ID is always placed first into a commutative
instruction. In other words, this instruction:
   bit_and result, v7, v5

Would be silently converted to this:
   bit_and result, v5, v7

This will allow these two logically-equivalent instructions to be
deduplicated:
   bit_and result, v7, v5
   bit_and result, v5, v7

Of course, deduplicating these ops can unlock additional free CSE/DCE.
The affected instructions are listed in http://review.skia.org/473238

Change-Id: Ib9beb79d6b72d7903184aaa9a53e8e5a02ae126d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/473239
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Herb Derby <herb@google.com>
2021-11-18 21:27:17 +00:00
John Stiles
626dbe195a Add test for commutative operations in SkVM.
SkVM should be able to optimize away these equivalent expressions:

	(intA & intB)   <->  (intB & intA)
	(intA ^ intB)   <->  (intB ^ intA)
	(intA | intB)   <->  (intB | intA)
	(intA + intB)   <->  (intB + intA)
	(intA * intB)   <->  (intB * intA)
	(intA == intB)  <->  (intB == intA)
	(intA != intB)  <->  (intB != intA)

These should be guaranteed by IEEE754 as well:

	(floatA + floatB)   <->  (floatB + floatA)
	(floatA * floatB)   <->  (floatB * floatA)

I've added a test to demonstrate existing behavior, which leaves these
optimizations on the table.

Change-Id: I01ce1d6f1cfadb3d77db405a83752c9dd52c99bd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/473238
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-18 21:16:48 +00:00
John Stiles
2fb8dac598 Add trace coordinates to SkVMDebugInfo.
The SkVMDebugInfo now includes an skvm::Coord that the caller is
responsible for filling in before converting the program. If it is set,
the value indicates the device coordinates that should be traced. If it
is unset, debug traces will not be emitted at all.

Within the SkVMCodeGenerator, we now have a new traceMask() call which
combines the current execution mask with the trace mask. Tracing opcodes
now pass the result of traceMask() instead of mask(). This will limit
trace data to the selected pixel, instead of tracing the entire draw.

Bug: skia:12614
Change-Id: I1f8ce7d18a31aa60a139a4a7335c2a285d6aee60
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/472798
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-17 21:56:42 +00:00
John Stiles
875447b871 Add SkVMFunctionInfo to debugger data.
We no longer indicate functions by their line number, which can be
ambiguous. The debug info now includes a list of function names which we
can refer to by index, and the `trace_call` opcode references functions
by their index in this list.

Change-Id: I4bdf2a6439637a07b116831fd2981f342c19ea4a
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/472796
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-11-17 21:56:13 +00:00
John Stiles
7ab86bd3e3 Add variable slot information to SkVMDebugInfo.
This assigns a human-readable name to a debug slot. The slot map is
emitted into skslc output files, and will be used in the future to
display human-readable names in the debugger.

Change-Id: I288358de305239005faa5814bd1d77a38b5e05b0
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/470400
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-15 14:24:08 +00:00
John Stiles
3aaed99930 Revert "Fix Metal codegen error with structs containing compound types."
This reverts commit 2a6c41571b.

Reason for revert: causing Mali G7x failures on tree

Original change's description:
> Fix Metal codegen error with structs containing compound types.
>
> While working on an unrelated test, I accidentally triggered a bug in
> Metal code generation. Our struct-equality helper functions did not
> properly handle vector fields. Wrapping each comparison in `all(...)`
> fixes the problem. (all() on a scalar is allowed and does nothing.)
>
> Our struct comparison tests now include a vector and a matrix.
>
> Change-Id: I59061ae9c3c3ab2c2dbdcb5257bc23e2257152af
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/470399
> Commit-Queue: John Stiles <johnstiles@google.com>
> Auto-Submit: John Stiles <johnstiles@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com,skcq-be@skia-corp.google.com.iam.gserviceaccount.com

Change-Id: Ieb5d5a1839978fb82525863488e9d54fdf44adbd
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/471097
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-11-12 23:09:34 +00:00
John Stiles
2a6c41571b Fix Metal codegen error with structs containing compound types.
While working on an unrelated test, I accidentally triggered a bug in
Metal code generation. Our struct-equality helper functions did not
properly handle vector fields. Wrapping each comparison in `all(...)`
fixes the problem. (all() on a scalar is allowed and does nothing.)

Our struct comparison tests now include a vector and a matrix.

Change-Id: I59061ae9c3c3ab2c2dbdcb5257bc23e2257152af
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/470399
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-12 15:54:41 +00:00
John Stiles
1991780081 Update LoopFloat/LoopInt tests to reduce hoisting.
Previously, none of our `runtime` tests relied on the input coordinate
in any way, so all of the logic was hoisted above the main loop in every
test. This CL adds an artificial reliance on the input coordinate so
that we have at least some SkVM tests with real code in the main loop.
This lets us see debug trace instructions interleaved with real code.

The input coordinate is clamped against a known uniform value
(`colorGreen` always contains 0101) so that the final test output
remains consistent in practice.

Additionally, I noticed that this test was only enabled in ES3, but
it doesn't seem to have anything ES3-specific in it, so it's now
enabled across the board.

Change-Id: Ie82f40b1060edb6071e300040ac59fb7d27094b0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/470397
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-11-12 13:45:59 +00:00
John Stiles
183f37d16a Add trace opcodes for function entry/exit.
This enables stepping over function calls automatically.

Change-Id: Ie15ed745377d851cb7752f651b573efa2cc8195f
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/469077
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-09 16:35:02 +00:00
John Stiles
efd828091d Emit trace_line ops to indicate for-statement next/test.
Previously, the for statement's "increment/test" expressions were
executed without moving the trace-line back up to the for statement.
When stepping through code, we will now explicitly step to the next/test
line on each loop iteration.

Change-Id: I5d9f005a42150670cec77218323cf932ee1cbdb0
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/469180
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-09 16:01:45 +00:00
John Stiles
70ae43148d Implement trace_var opcode.
This writes an entry to the trace buffer every time a slot value is
changed.

Change-Id: Iac3912be71ad654f70a7158e306e0643086c6cb0
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/469179
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-09 15:24:00 +00:00
John Stiles
15384b1195 Add a trace_line opcode to SkVM.
This will be used to populate a trace buffer for the SkSL debugger.
See http://go/sksl-tracing for details and rationale.

Change-Id: I4c218c65ff01c339cf460e97e41566860a694720
Bug: skia:12614
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/468436
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-11-05 19:55:39 +00:00
John Stiles
116d2e0e48 Fix ES2 conformance test 'in_vs_no_in'.
SkSL treated these two functions as distinct, even though they are not:
    void func(in float x);
    void func(float x);

The `in` modifier on a function parameter is the default state, making
these two prototypes functionally identical. We now strip off an `in`
modifier on a function definition. This gives us three potential states
for each param: nothing (meaning `in`), `out`, and `inout`.

Change-Id: Id2acb53ecaca98f86a7f6a83e0b9a375f9abe2b8
Bug: skia:12525
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/458257
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-10-11 22:27:37 +00:00
John Stiles
6d0234673a Optimize away empty for loops.
The fuzzer has found that it can get timeouts in SkVM by nesting loops
very very deeply, then at the bottom of the chain, making an inside-out
loop that runs for zero iterations. This has a calculated unrolled-size
of zero, but SkVM would still think hard about unrolling the (ultimately
empty) outer loops.

SkSL now optimizes away unrollable loops that run for zero iteratinons,
as well as empty unrollable loops. This should eliminate the fuzzer's
troublesome construct entirely.

Change-Id: Ic3ef7b7a6a9fc7ee7fb13eb7bd7f34c9bff57448
Bug: oss-fuzz:39661
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/456469
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-10-06 17:56:26 +00:00
John Stiles
906e9eb538 Emit qualifiers in the GLSL ES-required order.
This should fix a failure in the ES2 conformance suite's "const_in_int".

Change-Id: I8b5487749291ef57712b8fe6c3949dc7c3e76883
Bug: skia:12499
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/455157
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-10-01 19:09:43 +00:00
John Stiles
66aa1ded16 Allow precision qualifiers in function params.
Previously, `Type::applyPrecisionQualifiers` would return a new type
(e.g. `mediump + float` returned `half`) but left the precision
qualifier flags as-is. This was implemented that way because the
modifiers were already baked into a pool, so mutating them was
difficult.

The rewritten DSLParser does not share this limitation--every place
where applyPrecisionQualifiers is used, the Modifiers are easily
mutable. As a result, `applyPrecisionQualifiers` can now clear the
precision-qualifier bits on the Modifier, meaning that `half` and a
`mediump float` will generate the exact same Type/Modifier combination.

This change fixes a bug where precision qualifiers were not allowed on
function parameters. (See `check_parameters` in FunctionDeclaration.cpp
to pinpoint the cause of the error. A less-invasive fix could have just
marked those modifier bits as allowed in `check_parameters`, but this
fix addresses the root of the issue and is honestly how I wanted
`applyPrecisionQualifiers` to work all along.)

Change-Id: I331813efa54138f469a0d5bff2d274cd3ce64b70
Bug: skia:12489
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/455156
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
2021-10-01 18:59:27 +00:00
John Stiles
6868f78d40 Emit prototypes in Pipeline for every defined function.
In complex programs with multiple functions, the Inliner can cause code
to be reordered in ways that cause a function call to be raised above
its declaration.

The Pipeline stage code generator will now emit a prototype for every
function defined in the program, before emitting any function bodies at
all.

With this change, ES2 conformance test `copy_global_inout_on_call` now
passes.

Change-Id: I85485710a34b778adef3cbc4a7ebe110a21a2a03
Bug: skia:12488
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/454742
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-09-30 21:37:26 +00:00
John Stiles
31e4c38236 Add support for function prototypes in Pipeline stage.
Previously we did not have a Pipeline callback function for prototyping
a function, so prototypes would be discarded during translation. This
failure mode can be seen in http://review.skia.org/454741, where
FunctionPrototype.sksl is made more complex (thwarting the inliner).
This causes us to emit invalid GLSL, and dm asserts/fails in the SkSL
tests: http://screen/4PkEEWn4m4tF5e7

This CL makes the same changes to FunctionPrototype, but does not crash.

Change-Id: Ia342c7811a454f62f52677440d247e628a1bdc4f
Bug: skia:12488
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/454740
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-09-30 20:02:19 +00:00
Brian Osman
d26d0e6a47 Revert "Rewrite switch statements in GLSL strict-ES2 mode."
This reverts commit 45e3838006.

Reason for revert: Also need to rewrite them in actual ES2 mode.

Original change's description:
> Rewrite switch statements in GLSL strict-ES2 mode.
>
> Once this lands, switch statements will work everywhere--Metal, SPIR-V,
> GLSL, and SkVM.
>
> Change-Id: I2797d0a872de8be77bb9f7aa6acb93421d571d70
> Bug: skia:12450
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452356
> Commit-Queue: John Stiles <johnstiles@google.com>
> Auto-Submit: John Stiles <johnstiles@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>

Bug: skia:12450
Change-Id: I92656ed40289872405c0873f2c56a52b04e35b1d
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452556
Auto-Submit: Brian Osman <brianosman@google.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
2021-09-24 13:11:05 +00:00