diff --git a/cmd/gapit/state.go b/cmd/gapit/state.go index 49eacb4284..67cf8a915e 100644 --- a/cmd/gapit/state.go +++ b/cmd/gapit/state.go @@ -77,7 +77,7 @@ func (verb *stateVerb) Run(ctx context.Context, flags flag.FlagSet) error { verb.At = []uint64{uint64(boxedCapture.(*service.Capture).NumCommands) - 1} } - boxedTree, err := client.Get(ctx, c.Command(uint64(verb.At[0]), verb.At[1:]...).StateTreeAfter().Path()) + boxedTree, err := client.Get(ctx, c.Command(uint64(verb.At[0]), verb.At[1:]...).StateAfter().Tree().Path()) if err != nil { return log.Err(ctx, err, "Failed to load the command tree") } diff --git a/cmd/gapit/stresstest.go b/cmd/gapit/stresstest.go index fc78ba1952..bc98422d33 100644 --- a/cmd/gapit/stresstest.go +++ b/cmd/gapit/stresstest.go @@ -77,7 +77,7 @@ func (verb *stresstestVerb) Run(ctx context.Context, flags flag.FlagSet) error { go func() { defer wg.Done() ctx, _ := task.WithTimeout(ctx, duration) - boxedTree, err := client.Get(ctx, c.Command(at).StateTreeAfter().Path()) + boxedTree, err := client.Get(ctx, c.Command(at).StateAfter().Tree().Path()) if err != nil { return } diff --git a/gapic/src/main/com/google/gapid/models/ApiContext.java b/gapic/src/main/com/google/gapid/models/ApiContext.java index e9dfadfdc8..fa7d4baf4f 100644 --- a/gapic/src/main/com/google/gapid/models/ApiContext.java +++ b/gapic/src/main/com/google/gapid/models/ApiContext.java @@ -218,6 +218,20 @@ public int getPriority() { return context != null ? context.getPriority() : 0; } + public Path.State.Builder state(Path.State.Builder path) { + if (id != null) { + path.getContextBuilder().setData(id.getData()); + } + return path; + } + + public Path.StateTree.Builder stateTree(Path.StateTree.Builder path) { + if (id != null) { + path.getStateBuilder().getContextBuilder().setData(id.getData()); + } + return path; + } + public Path.Events.Builder events(Path.Events.Builder path) { path.getFilterBuilder().setContext(id); return path; diff --git a/gapic/src/main/com/google/gapid/models/ApiState.java b/gapic/src/main/com/google/gapid/models/ApiState.java index 1ea944fb72..0de81ba820 100644 --- a/gapic/src/main/com/google/gapid/models/ApiState.java +++ b/gapic/src/main/com/google/gapid/models/ApiState.java @@ -55,14 +55,14 @@ public class ApiState private final ObjectStore selection = ObjectStore.create(); public ApiState( - Shell shell, Client client, Follower follower, AtomStream atoms, ConstantSets constants) { + Shell shell, Client client, Follower follower, AtomStream atoms, ApiContext contexts, ConstantSets constants) { super(LOG, shell, client, Listener.class); this.constants = constants; atoms.addListener(new AtomStream.Listener() { @Override public void onAtomsSelected(AtomIndex index) { - load(stateTree(index), false); + load(stateTree(index, contexts.getSelectedContext()), false); } }); follower.addListener(new Follower.Listener() { @@ -76,7 +76,7 @@ public void onStateFollowed(Path.Any path) { @Override protected ListenableFuture doLoad(Path.Any path) { return Futures.transformAsync(client.get(path), - tree -> Futures.transform(client.get(Paths.any(tree.getStateTree().getRoot())), + tree -> Futures.transform(client.get(Paths.toAny(tree.getStateTree().getRoot())), val -> new RootNode( tree.getStateTree().getRoot().getTree(), val.getStateTreeNode()))); } @@ -115,7 +115,7 @@ protected void fireLoadedEvent() { public ListenableFuture load(Node node) { return node.load(shell, () -> Futures.transformAsync( - client.get(Paths.any(node.getPath(Path.StateTreeNode.newBuilder()))), + client.get(Paths.toAny(node.getPath(Path.StateTreeNode.newBuilder()))), value -> Futures.transform(constants.loadConstants(value.getStateTreeNode()), ignore -> new NodeData(value.getStateTreeNode())))); } diff --git a/gapic/src/main/com/google/gapid/models/AtomStream.java b/gapic/src/main/com/google/gapid/models/AtomStream.java index ef017cf607..630cb5865d 100644 --- a/gapic/src/main/com/google/gapid/models/AtomStream.java +++ b/gapic/src/main/com/google/gapid/models/AtomStream.java @@ -16,7 +16,6 @@ package com.google.gapid.models; import static com.google.gapid.proto.service.memory.Memory.PoolNames.Application_VALUE; -import static com.google.gapid.util.Paths.any; import static com.google.gapid.util.Paths.commandTree; import static com.google.gapid.util.Paths.lastCommand; import static com.google.gapid.util.Paths.observationsAfter; @@ -104,14 +103,14 @@ public void onContextSelected(FilteringContext ctx) { @Override protected ListenableFuture doLoad(Path.Any path) { return Futures.transformAsync(client.get(path), - tree -> Futures.transform(client.get(Paths.any(tree.getCommandTree().getRoot())), + tree -> Futures.transform(client.get(Paths.toAny(tree.getCommandTree().getRoot())), val -> new RootNode( tree.getCommandTree().getRoot().getTree(), val.getCommandTreeNode()))); } public ListenableFuture load(Node node) { return node.load(shell, () -> Futures.transformAsync( - client.get(any(node.getPath(Path.CommandTreeNode.newBuilder()))), v1 -> { + client.get(Paths.toAny(node.getPath(Path.CommandTreeNode.newBuilder()))), v1 -> { Service.CommandTreeNode data = v1.getCommandTreeNode(); if (data.getGroup().isEmpty() && data.hasCommands()) { return Futures.transform( @@ -122,7 +121,7 @@ public ListenableFuture load(Node node) { } public ListenableFuture loadCommand(Path.Command path) { - return Futures.transformAsync(client.get(any(path)), value -> + return Futures.transformAsync(client.get(Paths.toAny(path)), value -> Futures.transform(constants.loadConstants(value.getCommand()), ignore -> value.getCommand())); } diff --git a/gapic/src/main/com/google/gapid/models/ConstantSets.java b/gapic/src/main/com/google/gapid/models/ConstantSets.java index 405e5f4c86..9cccceab2e 100644 --- a/gapic/src/main/com/google/gapid/models/ConstantSets.java +++ b/gapic/src/main/com/google/gapid/models/ConstantSets.java @@ -34,7 +34,7 @@ public class ConstantSets { public ConstantSets(Client client) { this.cache = FutureCache.hardCache( - path -> Futures.transform(client.get(Paths.any(path)), Service.Value::getConstantSet), + path -> Futures.transform(client.get(Paths.toAny(path)), Service.Value::getConstantSet), result -> result.getConstantsCount() != 0); } diff --git a/gapic/src/main/com/google/gapid/models/Devices.java b/gapic/src/main/com/google/gapid/models/Devices.java index bf56ed0456..b5b0303b8a 100644 --- a/gapic/src/main/com/google/gapid/models/Devices.java +++ b/gapic/src/main/com/google/gapid/models/Devices.java @@ -118,7 +118,7 @@ public void loadDevices() { rpcController.start().listen(Futures.transformAsync(client.getDevices(), paths -> { List> results = Lists.newArrayList(); for (Path.Device path : paths) { - results.add(client.get(Paths.device(path))); + results.add(client.get(Paths.toAny(path))); } return Futures.allAsList(results); }), new UiErrorCallback, List, Void>(shell, LOG) { diff --git a/gapic/src/main/com/google/gapid/models/Follower.java b/gapic/src/main/com/google/gapid/models/Follower.java index 1f4cffde5d..25bb9b1df6 100644 --- a/gapic/src/main/com/google/gapid/models/Follower.java +++ b/gapic/src/main/com/google/gapid/models/Follower.java @@ -15,7 +15,6 @@ */ package com.google.gapid.models; -import static com.google.gapid.util.Paths.findState; import static java.util.logging.Level.FINE; import static java.util.logging.Level.WARNING; @@ -37,15 +36,13 @@ import com.google.gapid.util.Flags.Flag; import com.google.gapid.util.ObjectStore; import com.google.gapid.util.Paths; - -import org.eclipse.swt.widgets.Shell; - import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; +import org.eclipse.swt.widgets.Shell; /** * Model handling link following throughout the UI. @@ -209,7 +206,7 @@ public void onFollow(Path.Any path) { case FIELD: case ARRAY_INDEX: case MAP_INDEX: - if (findState(path) != null) { + if (Paths.contains(path, n -> n instanceof Path.State || n instanceof Path.GlobalState)) { listeners.fire().onStateFollowed(path); } else { LOG.log(WARNING, "Unknown follow path result: " + path); diff --git a/gapic/src/main/com/google/gapid/models/Models.java b/gapic/src/main/com/google/gapid/models/Models.java index c1435eec46..dd0425d5f7 100644 --- a/gapic/src/main/com/google/gapid/models/Models.java +++ b/gapic/src/main/com/google/gapid/models/Models.java @@ -59,7 +59,7 @@ public static Models create(Shell shell, Settings settings, Client client) { Timeline timeline = new Timeline(shell, client, capture, contexts); AtomStream atoms = new AtomStream(shell, client, capture, contexts, constants); Resources resources = new Resources(shell, client, capture); - ApiState state = new ApiState(shell, client, follower, atoms, constants); + ApiState state = new ApiState(shell, client, follower, atoms, contexts, constants); Reports reports = new Reports(shell, client, capture, devices, contexts); Thumbnails thumbs = new Thumbnails(client, devices, capture); return new Models(settings, follower, capture, devices, atoms, contexts, timeline, resources, diff --git a/gapic/src/main/com/google/gapid/util/Paths.java b/gapic/src/main/com/google/gapid/util/Paths.java index 89dd9d29cf..f4ec38d358 100644 --- a/gapic/src/main/com/google/gapid/util/Paths.java +++ b/gapic/src/main/com/google/gapid/util/Paths.java @@ -24,6 +24,9 @@ import com.google.gapid.proto.service.path.Path; import com.google.gapid.proto.service.vertex.Vertex; import com.google.gapid.views.Formatter; +import com.google.protobuf.GeneratedMessage; +import java.util.LinkedList; +import java.util.function.Predicate; /** * Path utilities. @@ -77,14 +80,16 @@ public static Path.State stateAfter(Path.Command command) { return Path.State.newBuilder().setAfter(command).build(); } - public static Path.Any stateTree(AtomIndex atom) { + public static Path.Any stateTree(AtomIndex atom, FilteringContext context) { if (atom == null) { return null; } return Path.Any.newBuilder() .setStateTree( - Path.StateTree.newBuilder().setAfter(atom.getCommand()).setArrayGroupSize(2000)) - .build(); + context.stateTree( + Path.StateTree.newBuilder() + .setState(stateAfter(atom.getCommand())) + .setArrayGroupSize(2000))).build(); } public static Path.Any stateTree(Path.ID tree, Path.Any statePath) { @@ -195,34 +200,6 @@ public static Path.Any blob(Image.ID id) { .setBlob(Path.Blob.newBuilder().setId(Path.ID.newBuilder().setData(id.getData()))).build(); } - public static Path.Any device(Path.Device device) { - return Path.Any.newBuilder().setDevice(device).build(); - } - - public static Path.Any any(Path.Command command) { - return Path.Any.newBuilder().setCommand(command).build(); - } - - public static Path.Any any(Path.CommandTreeNode node) { - return Path.Any.newBuilder().setCommandTreeNode(node).build(); - } - - public static Path.Any any(Path.CommandTreeNode.Builder node) { - return Path.Any.newBuilder().setCommandTreeNode(node).build(); - } - - public static Path.Any any(Path.ConstantSet constants) { - return Path.Any.newBuilder().setConstantSet(constants).build(); - } - - public static Path.Any any(Path.StateTreeNode node) { - return Path.Any.newBuilder().setStateTreeNode(node).build(); - } - - public static Path.Any any(Path.StateTreeNode.Builder node) { - return Path.Any.newBuilder().setStateTreeNode(node).build(); - } - /** * Compares a and b, returning -1 if a comes before b, 1 if b comes before a and 0 if they * are equal. @@ -246,600 +223,1435 @@ public static int compare(Path.Command a, Path.Command b) { return (a.getIndicesCount() == b.getIndicesCount()) ? 0 : -1; } - public static Path.State findState(Path.Any path) { - switch (path.getPathCase()) { - case STATE: - return path.getState(); - case FIELD: - return findState(path.getField()); - case ARRAY_INDEX: - return findState(path.getArrayIndex()); - case SLICE: - return findState(path.getSlice()); - case MAP_INDEX: - return findState(path.getMapIndex()); - default: - return null; - } + public static boolean contains(Path.Any path, Predicate predicate) { + return find(path, predicate) != null; } - public static Path.State findState(Path.Field path) { - switch (path.getStructCase()) { - case STATE: - return path.getState(); - case FIELD: - return findState(path.getField()); - case ARRAY_INDEX: - return findState(path.getArrayIndex()); - case SLICE: - return findState(path.getSlice()); - case MAP_INDEX: - return findState(path.getMapIndex()); - default: - return null; + public static Path.Any find(Path.Any path, Predicate predicate) { + for (Object p = toNode(path); p != null; p = parentOf(p)) { + if (predicate.test(p)) { + return toAny(p); + } } + return null; } - public static Path.State findState(Path.ArrayIndex path) { - switch (path.getArrayCase()) { - case FIELD: - return findState(path.getField()); - case ARRAY_INDEX: - return findState(path.getArrayIndex()); - case SLICE: - return findState(path.getSlice()); - case MAP_INDEX: - return findState(path.getMapIndex()); - default: - return null; - } + public static Path.GlobalState findGlobalState(Path.Any path) { + return find(path, n -> n instanceof Path.GlobalState).getGlobalState(); } - public static Path.State findState(Path.Slice path) { - switch (path.getArrayCase()) { - case FIELD: - return findState(path.getField()); - case ARRAY_INDEX: - return findState(path.getArrayIndex()); - case SLICE: - return findState(path.getSlice()); - case MAP_INDEX: - return findState(path.getMapIndex()); - default: - return null; - } + /** + * @return the unboxed path node from the {@link Path.Any}. + */ + public static Object toNode(Path.Any node) { + return dispatch(node, TO_NODE_VISITOR, null); } - public static Path.State findState(Path.MapIndex path) { - switch (path.getMapCase()) { - case STATE: - return path.getState(); - case FIELD: - return findState(path.getField()); - case ARRAY_INDEX: - return findState(path.getArrayIndex()); - case SLICE: - return findState(path.getSlice()); - case MAP_INDEX: - return findState(path.getMapIndex()); - default: - return null; - } + /** + * @return the path node boxed into a {@link Path.Any}. + */ + public static Path.Any toAny(Object node) { + return dispatch(node, TO_ANY_VISITOR, null); } - public static Path.Any reparent(Path.Any path, Path.State newState) { - Path.Any.Builder builder = path.toBuilder(); - switch (path.getPathCase()) { - case STATE: - return builder.setState(newState).build(); - case FIELD: - return reparent(builder.getFieldBuilder(), newState) ? builder.build() : null; - case ARRAY_INDEX: - return reparent(builder.getArrayIndexBuilder(), newState) ? builder.build() : null; - case SLICE: - return reparent(builder.getSliceBuilder(), newState) ? builder.build() : null; - case MAP_INDEX: - return reparent(builder.getMapIndexBuilder(), newState) ? builder.build() : null; - default: - return null; - } + /** + * @return the parent path node of the given path node. + */ + public static Object parentOf(Object path) { + return dispatch(path, GET_PARENT_VISITOR, null); } - public static boolean reparent(Path.Field.Builder path, Path.State newState) { - switch (path.getStructCase()) { - case STATE: - path.setState(newState); - return true; - case FIELD: - return reparent(path.getFieldBuilder(), newState); - case ARRAY_INDEX: - return reparent(path.getArrayIndexBuilder(), newState); - case SLICE: - return reparent(path.getSliceBuilder(), newState); - case MAP_INDEX: - return reparent(path.getMapIndexBuilder(), newState); - default: - return false; - } + /** + * @return a copy of the given the path node with its parent set to the given parent. + */ + public static Object setParent(Object path, Object parent) { + return dispatch(path, SET_PARENT_VISITOR, parent); } - public static boolean reparent(Path.ArrayIndex.Builder path, Path.State newState) { - switch (path.getArrayCase()) { - case FIELD: - return reparent(path.getFieldBuilder(), newState); - case ARRAY_INDEX: - return reparent(path.getArrayIndexBuilder(), newState); - case SLICE: - return reparent(path.getSliceBuilder(), newState); - case MAP_INDEX: - return reparent(path.getMapIndexBuilder(), newState); - default: - return false; - } + /** + * @return the path as a string. + */ + public static String toString(Object path) { + return dispatch(path, PRINT_VISITOR, new StringBuilder()).toString(); } - public static boolean reparent(Path.Slice.Builder path, Path.State newState) { - switch (path.getArrayCase()) { - case FIELD: - return reparent(path.getFieldBuilder(), newState); - case ARRAY_INDEX: - return reparent(path.getArrayIndexBuilder(), newState); - case SLICE: - return reparent(path.getSliceBuilder(), newState); - case MAP_INDEX: - return reparent(path.getMapIndexBuilder(), newState); - default: - return false; + /** + * @return the path with the {@link Path.GlobalState} ancestor replaced with state. If there is no + * {@link Path.GlobalState} ancestor, then null is returned. + */ + public static Path.Any reparent(Path.Any path, Path.GlobalState state) { + LinkedList nodes = new LinkedList(); + boolean found = false; + for (Object p = toNode(path); p != null; p = parentOf(p)) { + if (p instanceof Path.GlobalState) { + found = true; + break; + } + nodes.addFirst(p); } - } - - public static boolean reparent(Path.MapIndex.Builder path, Path.State newState) { - switch (path.getMapCase()) { - case STATE: - path.setState(newState); - return true; - case FIELD: - return reparent(path.getFieldBuilder(), newState); - case ARRAY_INDEX: - return reparent(path.getArrayIndexBuilder(), newState); - case SLICE: - return reparent(path.getSliceBuilder(), newState); - case MAP_INDEX: - return reparent(path.getMapIndexBuilder(), newState); - default: - return false; + if (!found) { + return null; } + Object head = state; + for (Object node : nodes) { + head = setParent(node, head); + } + return toAny(head); } - public static String toString(Path.ID id) { - return ProtoDebugTextFormat.shortDebugString(id); - } - - public static String toString(Image.ID id) { - return ProtoDebugTextFormat.shortDebugString(id); + /** + * Visitor is the interface implemented by types that operate each of the path types. + * @param the type of the result value. + * @param the type of the argument value. + */ + private interface Visitor { + R visit(Image.ID path, A arg); + R visit(Path.API path, A arg); + R visit(Path.ArrayIndex path, A arg); + R visit(Path.As path, A arg); + R visit(Path.Blob path, A arg); + R visit(Path.Capture path, A arg); + R visit(Path.ConstantSet path, A arg); + R visit(Path.Command path, A arg); + R visit(Path.Commands path, A arg); + R visit(Path.CommandTree path, A arg); + R visit(Path.CommandTreeNode path, A arg); + R visit(Path.CommandTreeNodeForCommand path, A arg); + R visit(Path.Context path, A arg); + R visit(Path.Contexts path, A arg); + R visit(Path.Device path, A arg); + R visit(Path.Events path, A arg); + R visit(Path.FramebufferObservation path, A arg); + R visit(Path.Field path, A arg); + R visit(Path.GlobalState path, A arg); + R visit(Path.ID path, A arg); + R visit(Path.ImageInfo path, A arg); + R visit(Path.MapIndex path, A arg); + R visit(Path.Memory path, A arg); + R visit(Path.Mesh path, A arg); + R visit(Path.Parameter path, A arg); + R visit(Path.Report path, A arg); + R visit(Path.ResourceData path, A arg); + R visit(Path.Resources path, A arg); + R visit(Path.Result path, A arg); + R visit(Path.Slice path, A arg); + R visit(Path.State path, A arg); + R visit(Path.StateTree path, A arg); + R visit(Path.StateTreeNode path, A arg); + R visit(Path.StateTreeNodeForPath path, A arg); + R visit(Path.Thumbnail path, A arg); } - public static String toString(Path.Any path) { + /** + * Unboxes the path node from the {@link Path.Any} and dispatches the node to the visitor. + * Throws an exception if the path is not an expected type. + */ + private static T dispatchAny(Path.Any path, Visitor visitor, A arg) { switch (path.getPathCase()) { case API: - return toString(path.getApi()); + return visitor.visit(path.getApi(), arg); case ARRAY_INDEX: - return toString(path.getArrayIndex()); + return visitor.visit(path.getArrayIndex(), arg); case AS: - return toString(path.getAs()); + return visitor.visit(path.getAs(), arg); case BLOB: - return toString(path.getBlob()); + return visitor.visit(path.getBlob(), arg); case CAPTURE: - return toString(path.getCapture()); + return visitor.visit(path.getCapture(), arg); + case CONSTANT_SET: + return visitor.visit(path.getConstantSet(), arg); case COMMAND: - return toString(path.getCommand()); + return visitor.visit(path.getCommand(), arg); case COMMANDS: - return toString(path.getCommands()); + return visitor.visit(path.getCommands(), arg); case COMMAND_TREE: - return toString(path.getCommandTree()); + return visitor.visit(path.getCommandTree(), arg); case COMMAND_TREE_NODE: - return toString(path.getCommandTreeNode()); + return visitor.visit(path.getCommandTreeNode(), arg); case COMMAND_TREE_NODE_FOR_COMMAND: - return toString(path.getCommandTreeNodeForCommand()); - case CONSTANT_SET: - return toString(path.getConstantSet()); + return visitor.visit(path.getCommandTreeNodeForCommand(), arg); case CONTEXT: - return toString(path.getContext()); + return visitor.visit(path.getContext(), arg); case CONTEXTS: - return toString(path.getContexts()); + return visitor.visit(path.getContexts(), arg); case DEVICE: - return toString(path.getDevice()); + return visitor.visit(path.getDevice(), arg); case EVENTS: - return toString(path.getEvents()); + return visitor.visit(path.getEvents(), arg); + case FBO: + return visitor.visit(path.getFbo(), arg); case FIELD: - return toString(path.getField()); + return visitor.visit(path.getField(), arg); + case GLOBAL_STATE: + return visitor.visit(path.getGlobalState(), arg); case IMAGE_INFO: - return toString(path.getImageInfo()); + return visitor.visit(path.getImageInfo(), arg); case MAP_INDEX: - return toString(path.getMapIndex()); + return visitor.visit(path.getMapIndex(), arg); case MEMORY: - return toString(path.getMemory()); + return visitor.visit(path.getMemory(), arg); case MESH: - return toString(path.getMesh()); + return visitor.visit(path.getMesh(), arg); case PARAMETER: - return toString(path.getParameter()); + return visitor.visit(path.getParameter(), arg); case REPORT: - return toString(path.getReport()); - case RESOURCES: - return toString(path.getResources()); + return visitor.visit(path.getReport(), arg); case RESOURCE_DATA: - return toString(path.getResourceData()); + return visitor.visit(path.getResourceData(), arg); + case RESOURCES: + return visitor.visit(path.getResources(), arg); case RESULT: - return toString(path.getResult()); + return visitor.visit(path.getResult(), arg); case SLICE: - return toString(path.getSlice()); + return visitor.visit(path.getSlice(), arg); case STATE: - return toString(path.getState()); + return visitor.visit(path.getState(), arg); case STATE_TREE: - return toString(path.getStateTree()); + return visitor.visit(path.getStateTree(), arg); case STATE_TREE_NODE: - return toString(path.getStateTreeNode()); + return visitor.visit(path.getStateTreeNode(), arg); case STATE_TREE_NODE_FOR_PATH: - return toString(path.getStateTreeNodeForPath()); + return visitor.visit(path.getStateTreeNodeForPath(), arg); case THUMBNAIL: - return toString(path.getThumbnail()); + return visitor.visit(path.getThumbnail(), arg); default: - return ProtoDebugTextFormat.shortDebugString(path); + throw new RuntimeException("Unexpected path case: " + path.getPathCase()); } } - public static String toString(Path.API api) { - return "API{" + toString(api.getId()) + "}"; + /** + * Dispatches the path node to the visitor. + * Throws an exception if the path is not an expected type. + */ + private static T dispatch(Object path, Visitor visitor, A arg) { + if (path instanceof Path.Any) { + return dispatchAny((Path.Any)path, visitor, arg); + } else if (path instanceof Image.ID) { + return visitor.visit((Image.ID)path, arg); + } else if (path instanceof Path.API) { + return visitor.visit((Path.API)path, arg); + } else if (path instanceof Path.ArrayIndex) { + return visitor.visit((Path.ArrayIndex)path, arg); + } else if (path instanceof Path.As) { + return visitor.visit((Path.As)path, arg); + } else if (path instanceof Path.Blob) { + return visitor.visit((Path.Blob)path, arg); + } else if (path instanceof Path.Capture) { + return visitor.visit((Path.Capture)path, arg); + } else if (path instanceof Path.ConstantSet) { + return visitor.visit((Path.ConstantSet)path, arg); + } else if (path instanceof Path.Command) { + return visitor.visit((Path.Command)path, arg); + } else if (path instanceof Path.Commands) { + return visitor.visit((Path.Commands)path, arg); + } else if (path instanceof Path.CommandTree) { + return visitor.visit((Path.CommandTree)path, arg); + } else if (path instanceof Path.CommandTreeNode) { + return visitor.visit((Path.CommandTreeNode)path, arg); + } else if (path instanceof Path.CommandTreeNodeForCommand) { + return visitor.visit((Path.CommandTreeNodeForCommand)path, arg); + } else if (path instanceof Path.Context) { + return visitor.visit((Path.Context)path, arg); + } else if (path instanceof Path.Contexts) { + return visitor.visit((Path.Contexts)path, arg); + } else if (path instanceof Path.Device) { + return visitor.visit((Path.Device)path, arg); + } else if (path instanceof Path.Events) { + return visitor.visit((Path.Events)path, arg); + } else if (path instanceof Path.FramebufferObservation) { + return visitor.visit((Path.FramebufferObservation)path, arg); + } else if (path instanceof Path.Field) { + return visitor.visit((Path.Field)path, arg); + } else if (path instanceof Path.GlobalState) { + return visitor.visit((Path.GlobalState)path, arg); + } else if (path instanceof Path.ID) { + return visitor.visit((Path.ID)path, arg); + } else if (path instanceof Path.ImageInfo) { + return visitor.visit((Path.ImageInfo)path, arg); + } else if (path instanceof Path.MapIndex) { + return visitor.visit((Path.MapIndex)path, arg); + } else if (path instanceof Path.Memory) { + return visitor.visit((Path.Memory)path, arg); + } else if (path instanceof Path.Mesh) { + return visitor.visit((Path.Mesh)path, arg); + } else if (path instanceof Path.Parameter) { + return visitor.visit((Path.Parameter)path, arg); + } else if (path instanceof Path.Report) { + return visitor.visit((Path.Report)path, arg); + } else if (path instanceof Path.ResourceData) { + return visitor.visit((Path.ResourceData)path, arg); + } else if (path instanceof Path.Resources) { + return visitor.visit((Path.Resources)path, arg); + } else if (path instanceof Path.Result) { + return visitor.visit((Path.Result)path, arg); + } else if (path instanceof Path.Slice) { + return visitor.visit((Path.Slice)path, arg); + } else if (path instanceof Path.State) { + return visitor.visit((Path.State)path, arg); + } else if (path instanceof Path.StateTree) { + return visitor.visit((Path.StateTree)path, arg); + } else if (path instanceof Path.StateTreeNode) { + return visitor.visit((Path.StateTreeNode)path, arg); + } else if (path instanceof Path.StateTreeNodeForPath) { + return visitor.visit((Path.StateTreeNodeForPath)path, arg); + } else if (path instanceof Path.Thumbnail) { + return visitor.visit((Path.Thumbnail)path, arg); + } else if (path instanceof GeneratedMessage.Builder) { + return dispatch(((GeneratedMessage.Builder)path).build(), visitor, arg); + } else { + throw new RuntimeException("Unexpected path type: " + path.getClass().getName()); + } } - public static String toString(Path.ArrayIndex arrayIndex) { - String parent; - switch (arrayIndex.getArrayCase()) { - case ARRAY_INDEX: - parent = toString(arrayIndex.getArrayIndex()); - break; - case FIELD: - parent = toString(arrayIndex.getField()); - break; - case MAP_INDEX: - parent = toString(arrayIndex.getMapIndex()); - break; - case PARAMETER: - parent = toString(arrayIndex.getParameter()); - break; - case REPORT: - parent = toString(arrayIndex.getReport()); - break; - case SLICE: - parent = toString(arrayIndex.getSlice()); - break; - default: - parent = "??"; - break; + /** + * {@link Visitor} that simply returns the node type. Used by {@link #toNode(Path.Any)}. + */ + private static final Visitor TO_NODE_VISITOR = new Visitor() { + @Override public Object visit(Image.ID path, Void ignored) { return path; } + @Override public Object visit(Path.API path, Void ignored) { return path; } + @Override public Object visit(Path.ArrayIndex path, Void ignored) { return path; } + @Override public Object visit(Path.As path, Void ignored) { return path; } + @Override public Object visit(Path.Blob path, Void ignored) { return path; } + @Override public Object visit(Path.Capture path, Void ignored) { return path; } + @Override public Object visit(Path.ConstantSet path, Void ignored) { return path; } + @Override public Object visit(Path.Command path, Void ignored) { return path; } + @Override public Object visit(Path.Commands path, Void ignored) { return path; } + @Override public Object visit(Path.CommandTree path, Void ignored) { return path; } + @Override public Object visit(Path.CommandTreeNode path, Void ignored) { return path; } + @Override public Object visit(Path.CommandTreeNodeForCommand path, Void ignored) { return path; } + @Override public Object visit(Path.Context path, Void ignored) { return path; } + @Override public Object visit(Path.Contexts path, Void ignored) { return path; } + @Override public Object visit(Path.Device path, Void ignored) { return path; } + @Override public Object visit(Path.Events path, Void ignored) { return path; } + @Override public Object visit(Path.FramebufferObservation path, Void ignored) { return path; } + @Override public Object visit(Path.Field path, Void ignored) { return path; } + @Override public Object visit(Path.GlobalState path, Void ignored) { return path; } + @Override public Object visit(Path.ID path, Void ignored) { return path; } + @Override public Object visit(Path.ImageInfo path, Void ignored) { return path; } + @Override public Object visit(Path.MapIndex path, Void ignored) { return path; } + @Override public Object visit(Path.Memory path, Void ignored) { return path; } + @Override public Object visit(Path.Mesh path, Void ignored) { return path; } + @Override public Object visit(Path.Parameter path, Void ignored) { return path; } + @Override public Object visit(Path.Report path, Void ignored) { return path; } + @Override public Object visit(Path.ResourceData path, Void ignored) { return path; } + @Override public Object visit(Path.Resources path, Void ignored) { return path; } + @Override public Object visit(Path.Result path, Void ignored) { return path; } + @Override public Object visit(Path.Slice path, Void ignored) { return path; } + @Override public Object visit(Path.State path, Void ignored) { return path; } + @Override public Object visit(Path.StateTree path, Void ignored) { return path; } + @Override public Object visit(Path.StateTreeNode path, Void ignored) { return path; } + @Override public Object visit(Path.StateTreeNodeForPath path, Void ignored) { return path; } + @Override public Object visit(Path.Thumbnail path, Void ignored) { return path; } + }; + + /** + * {@link Visitor} that returns the passed node type boxed in a {@link Path.Any}. + * Used by {@link #toAny(Object)}. + */ + private static final Visitor TO_ANY_VISITOR = new Visitor() { + @Override + public Path.Any visit(Image.ID path, Void ignored) { + throw new RuntimeException("Image.ID cannot be stored in a Path.Any"); } - return parent + "[" + UnsignedLongs.toString(arrayIndex.getIndex()) + "]"; - } - public static String toString(Path.As as) { - String parent; - switch (as.getFromCase()) { - case ARRAY_INDEX: - parent = toString(as.getArrayIndex()); - break; - case FIELD: - parent = toString(as.getField()); - break; - case IMAGE_INFO: - parent = toString(as.getImageInfo()); - break; - case MAP_INDEX: - parent = toString(as.getMapIndex()); - break; - case MESH: - parent = toString(as.getMesh()); - break; - case RESOURCE_DATA: - parent = toString(as.getResourceData()); - break; - case SLICE: - parent = toString(as.getSlice()); - break; - default: - parent = "??"; - break; + @Override + public Path.Any visit(Path.API path, Void ignored) { + return Path.Any.newBuilder().setApi(path).build(); } - switch (as.getToCase()) { - case IMAGE_FORMAT: - return parent + ".as(" + as.getImageFormat().getName() + ")"; // TODO - case VERTEX_BUFFER_FORMAT: - return parent + ".as(VBF)"; // TODO - default: - return parent + ".as(??)"; + + @Override + public Path.Any visit(Path.ArrayIndex path, Void ignored) { + return Path.Any.newBuilder().setArrayIndex(path).build(); } - } - public static String toString(Path.Blob blob) { - return "blob{" + toString(blob.getId()) + "}"; - } + @Override + public Path.Any visit(Path.As path, Void ignored) { + return Path.Any.newBuilder().setAs(path).build(); + } - public static String toString(Path.Capture capture) { - return "capture{" + toString(capture.getId()) + "}"; - } + @Override + public Path.Any visit(Path.Blob path, Void ignored) { + return Path.Any.newBuilder().setBlob(path).build(); + } - public static String toString(Path.Command command) { - return toString(command.getCapture()) + ".command[" + Formatter.atomIndex(command) + "]"; - } + @Override + public Path.Any visit(Path.Capture path, Void ignored) { + return Path.Any.newBuilder().setCapture(path).build(); + } - public static String toString(Path.Commands commands) { - return toString(commands.getCapture()) + ".command[" + Formatter.firstIndex(commands) + ":" - + Formatter.lastIndex(commands) + "]"; - } + @Override + public Path.Any visit(Path.ConstantSet path, Void ignored) { + return Path.Any.newBuilder().setConstantSet(path).build(); + } - public static String toString(Path.CommandTree tree) { - StringBuilder sb = new StringBuilder().append(toString(tree.getCapture())).append(".tree"); - append(sb, tree.getFilter()).append('['); - if (tree.getGroupByApi()) sb.append('A'); - if (tree.getGroupByThread()) sb.append('T'); - if (tree.getGroupByContext()) sb.append('C'); - if (tree.getIncludeNoContextGroups()) sb.append('n'); - if (tree.getGroupByFrame()) sb.append('F'); - if (tree.getAllowIncompleteFrame()) sb.append('i'); - if (tree.getGroupByDrawCall()) sb.append('D'); - if (tree.getGroupByUserMarkers()) sb.append('M'); - if (tree.getMaxChildren() != 0) { - sb.append(",max=").append(tree.getMaxChildren()); + @Override + public Path.Any visit(Path.Command path, Void ignored) { + return Path.Any.newBuilder().setCommand(path).build(); } - return sb.append(']').toString(); - } - public static StringBuilder append(StringBuilder sb, Path.CommandFilter filter) { - String sep = "(", end = ""; - if (filter.hasContext()) { - sb.append(sep).append("context=").append(toString(filter.getContext())); - sep = ","; - end = ")"; + @Override + public Path.Any visit(Path.Commands path, Void ignored) { + return Path.Any.newBuilder().setCommands(path).build(); } - if (filter.getThreadsCount() > 0) { - sb.append(sep).append("threads=").append(filter.getThreadsList()); - sep = ","; - end = ")"; + + @Override + public Path.Any visit(Path.CommandTree path, Void ignored) { + return Path.Any.newBuilder().setCommandTree(path).build(); } - return sb.append(end); - } - public static String toString(Path.CommandTreeNode n) { - return "tree{" + toString(n.getTree()) + "}.node(" + Formatter.index(n.getIndicesList()) + ")"; - } + @Override + public Path.Any visit(Path.CommandTreeNode path, Void ignored) { + return Path.Any.newBuilder().setCommandTreeNode(path).build(); + } - public static String toString(Path.CommandTreeNodeForCommand nfc) { - return "tree{" + toString(nfc.getTree()) + "}.command(" + toString(nfc.getCommand()) + ")"; - } + @Override + public Path.Any visit(Path.CommandTreeNodeForCommand path, Void ignored) { + return Path.Any.newBuilder().setCommandTreeNodeForCommand(path).build(); + } - public static String toString(Path.ConstantSet cs) { - return toString(cs.getApi()) + ".constants[" + cs.getIndex() + "]"; - } + @Override + public Path.Any visit(Path.Context path, Void ignored) { + return Path.Any.newBuilder().setContext(path).build(); + } - public static String toString(Path.Context context) { - return toString(context.getCapture()) + ".context[" + toString(context.getId()) + "]"; - } + @Override + public Path.Any visit(Path.Contexts path, Void ignored) { + return Path.Any.newBuilder().setContexts(path).build(); + } - public static String toString(Path.Contexts contexts) { - return toString(contexts.getCapture()) + ".contexts"; - } + @Override + public Path.Any visit(Path.Device path, Void ignored) { + return Path.Any.newBuilder().setDevice(path).build(); + } - public static String toString(Path.Device device) { - return "device{" + toString(device.getId()) + "}"; - } + @Override + public Path.Any visit(Path.Events path, Void ignored) { + return Path.Any.newBuilder().setEvents(path).build(); + } - public static String toString(Path.Events events) { - StringBuilder sb = new StringBuilder().append(toString(events.getCapture())).append(".events"); - append(sb, events.getFilter()).append('['); - if (events.getFirstInFrame()) sb.append("Fs"); - if (events.getLastInFrame()) sb.append("Fe"); - if (events.getClears()) sb.append("C"); - if (events.getDrawCalls()) sb.append("D"); - if (events.getUserMarkers()) sb.append("M"); - if (events.getPushUserMarkers()) sb.append("Ms"); - if (events.getPopUserMarkers()) sb.append("Me"); - if (events.getFramebufferObservations()) sb.append("O"); - return sb.append(']').toString(); - } + @Override + public Path.Any visit(Path.FramebufferObservation path, Void ignored) { + return Path.Any.newBuilder().setFbo(path).build(); + } - public static String toString(Path.Field field) { - String parent; - switch (field.getStructCase()) { - case FIELD: - parent = toString(field.getField()); - break; - case SLICE: - parent = toString(field.getSlice()); - break; - case ARRAY_INDEX: - parent = toString(field.getArrayIndex()); - break; - case MAP_INDEX: - parent = toString(field.getMapIndex()); - break; - case STATE: - parent = toString(field.getState()); - break; - case PARAMETER: - parent = toString(field.getParameter()); - break; - default: - parent = "??"; - break; + @Override + public Path.Any visit(Path.Field path, Void ignored) { + return Path.Any.newBuilder().setField(path).build(); } - return parent + "." + field.getName(); - } - public static String toString(Path.ImageInfo image) { - return "image{" + toString(image.getId()) + "}"; - } + @Override + public Path.Any visit(Path.GlobalState path, Void ignored) { + return Path.Any.newBuilder().setGlobalState(path).build(); + } - public static String toString(Path.MapIndex mapIndex) { - String parent; - switch (mapIndex.getMapCase()) { - case FIELD: - parent = toString(mapIndex.getField()); - break; - case SLICE: - parent = toString(mapIndex.getSlice()); - break; - case ARRAY_INDEX: - parent = toString(mapIndex.getArrayIndex()); - break; - case MAP_INDEX: - parent = toString(mapIndex.getMapIndex()); - break; - case STATE: - parent = toString(mapIndex.getState()); - break; - case PARAMETER: - parent = toString(mapIndex.getParameter()); - break; - default: - parent = "??"; - break; + @Override + public Path.Any visit(Path.ID path, Void ignored) { + throw new RuntimeException("Path.ID cannot be stored in a Path.Any"); } - switch (mapIndex.getKeyCase()) { - case BOX: - return parent + "[" + Formatter.toString(mapIndex.getBox(), null, true) + "]"; - default: - return parent + "[??]"; + + @Override + public Path.Any visit(Path.ImageInfo path, Void ignored) { + return Path.Any.newBuilder().setImageInfo(path).build(); } - } - public static String toString(Path.Memory mem) { - StringBuilder sb = new StringBuilder().append(toString(mem.getAfter())).append(".memory(") - .append("pool:").append(mem.getPool()).append(',') - .append(Long.toHexString(mem.getAddress())).append('[').append(mem.getSize()).append(']'); - if (mem.getExcludeData()) sb.append(",nodata"); - if (mem.getExcludeObserved()) sb.append(",noobs"); - return sb.append(')').toString(); - } + @Override + public Path.Any visit(Path.MapIndex path, Void ignored) { + return Path.Any.newBuilder().setMapIndex(path).build(); + } - public static String toString(Path.Mesh mesh) { - StringBuilder sb = new StringBuilder(); - switch (mesh.getObjectCase()) { - case COMMAND: - sb.append(toString(mesh.getCommand())); - break; - case COMMAND_TREE_NODE: - sb.append(toString(mesh.getCommandTreeNode())); - break; - default: - sb.append("??"); - break; + @Override + public Path.Any visit(Path.Memory path, Void ignored) { + return Path.Any.newBuilder().setMemory(path).build(); } - sb.append(".mesh("); - if (mesh.getOptions().getFaceted()) sb.append("faceted"); - return sb.append(')').toString(); - } - public static String toString(Path.Parameter parameter) { - return toString(parameter.getCommand()) + "." + parameter.getName(); - } + @Override + public Path.Any visit(Path.Mesh path, Void ignored) { + return Path.Any.newBuilder().setMesh(path).build(); + } - public static String toString(Path.Report report) { - StringBuilder sb = new StringBuilder().append(toString(report.getCapture())).append(".report"); - if (report.hasDevice()) { - sb.append('[').append(toString(report.getDevice())); + @Override + public Path.Any visit(Path.Parameter path, Void ignored) { + return Path.Any.newBuilder().setParameter(path).build(); } - return append(sb, report.getFilter()).toString(); - } - public static String toString(Path.ResourceData res) { - return toString(res.getAfter()) + ".resource{" + toString(res.getId()) + "}"; - } + @Override + public Path.Any visit(Path.Report path, Void ignored) { + return Path.Any.newBuilder().setReport(path).build(); + } - public static String toString(Path.Resources res) { - return toString(res.getCapture()) + ".resources"; - } + @Override + public Path.Any visit(Path.ResourceData path, Void ignored) { + return Path.Any.newBuilder().setResourceData(path).build(); + } - public static String toString(Path.Result result) { - return toString(result.getCommand()) + "."; - } + @Override + public Path.Any visit(Path.Resources path, Void ignored) { + return Path.Any.newBuilder().setResources(path).build(); + } - public static String toString(Path.Slice slice) { - String parent; - switch (slice.getArrayCase()) { - case FIELD: - parent = toString(slice.getField()); - break; - case SLICE: - parent = toString(slice.getSlice()); - break; - case ARRAY_INDEX: - parent = toString(slice.getArrayIndex()); - break; - case MAP_INDEX: - parent = toString(slice.getMapIndex()); - break; - case PARAMETER: - parent = toString(slice.getParameter()); - break; - default: - parent = "??"; - break; + @Override + public Path.Any visit(Path.Result path, Void ignored) { + return Path.Any.newBuilder().setResult(path).build(); } - return parent + "[" + slice.getStart() + ":" + slice.getEnd() + "]"; - } - public static String toString(Path.State state) { - return toString(state.getAfter()) + ".state"; - } + @Override + public Path.Any visit(Path.Slice path, Void ignored) { + return Path.Any.newBuilder().setSlice(path).build(); + } - public static String toString(Path.StateTree tree) { - StringBuilder sb = new StringBuilder().append(toString(tree.getAfter())).append(".stateTree"); - if (tree.getArrayGroupSize() > 0) { - sb.append("(groupSize=").append(tree.getArrayGroupSize()).append(')'); + @Override + public Path.Any visit(Path.State path, Void ignored) { + return Path.Any.newBuilder().setState(path).build(); } - return sb.toString(); - } - public static String toString(Path.StateTreeNode node) { - return "stateTree{" + toString(node.getTree()) + "}.node(" - + Formatter.index(node.getIndicesList()) + ")"; - } + @Override + public Path.Any visit(Path.StateTree path, Void ignored) { + return Path.Any.newBuilder().setStateTree(path).build(); + } - public static String toString(Path.StateTreeNodeForPath nfp) { - return "stateTree{" + toString(nfp.getTree()) + "}.path(" + toString(nfp.getMember()) + ")"; - } + @Override + public Path.Any visit(Path.StateTreeNode path, Void ignored) { + return Path.Any.newBuilder().setStateTreeNode(path).build(); + } - public static String toString(Path.Thumbnail thumbnail) { - StringBuilder sb = new StringBuilder(); - switch (thumbnail.getObjectCase()) { - case RESOURCE: - sb.append(toString(thumbnail.getResource())); - break; - case COMMAND: - sb.append(toString(thumbnail.getCommand())); - break; - case COMMAND_TREE_NODE: - sb.append(toString(thumbnail.getCommandTreeNode())); - break; - default: - sb.append("??"); - break; + @Override + public Path.Any visit(Path.StateTreeNodeForPath path, Void ignored) { + return Path.Any.newBuilder().setStateTreeNodeForPath(path).build(); } - sb.append(".thumbnail"); - String sep = "(", end = ""; - if (thumbnail.getDesiredMaxWidth() > 0) { - sb.append(sep).append("w=").append(thumbnail.getDesiredMaxWidth()); - sep = ","; - end = ")"; + + @Override + public Path.Any visit(Path.Thumbnail path, Void ignored) { + return Path.Any.newBuilder().setThumbnail(path).build(); } - if (thumbnail.getDesiredMaxHeight() > 0) { - sb.append(sep).append("h=").append(thumbnail.getDesiredMaxHeight()); - sep = ","; - end = ")"; + }; + + /** + * {@link Visitor} that returns the parent node of the given path node. + * Used by {@link #parentOf(Object)}. + */ + private static final Visitor GET_PARENT_VISITOR = new Visitor() { + @Override + public Object visit(Image.ID path, Void ignored) { + return null; } - if (thumbnail.hasDesiredFormat()) { - sb.append(sep).append("f=").append(thumbnail.getDesiredFormat().getName()); // TODO - sep = ","; - end = ")"; + + @Override + public Object visit(Path.API path, Void ignored) { + return null; } - return sb.append(end).toString(); - } + + @Override + public Object visit(Path.ArrayIndex path, Void ignored) { + switch (path.getArrayCase()) { + case FIELD: + return path.getField(); + case ARRAY_INDEX: + return path.getArrayIndex(); + case SLICE: + return path.getSlice(); + case MAP_INDEX: + return path.getMapIndex(); + default: + return null; + } + } + + @Override + public Object visit(Path.As path, Void ignored) { + switch (path.getFromCase()) { + case FIELD: + return path.getField(); + case SLICE: + return path.getSlice(); + case ARRAY_INDEX: + return path.getArrayIndex(); + case MAP_INDEX: + return path.getMapIndex(); + case IMAGE_INFO: + return path.getImageInfo(); + case RESOURCE_DATA: + return path.getResourceData(); + case MESH: + return path.getMesh(); + default: + return null; + } + } + + @Override + public Object visit(Path.Blob path, Void ignored) { + return null; + } + + @Override + public Object visit(Path.Capture path, Void ignored) { + return null; + } + + @Override + public Object visit(Path.ConstantSet path, Void ignored) { + return path.getApi(); + } + + @Override + public Object visit(Path.Command path, Void ignored) { + return path.getCapture(); + } + + @Override + public Object visit(Path.Commands path, Void ignored) { + return path.getCapture(); + } + + @Override + public Object visit(Path.CommandTree path, Void ignored) { + return path.getCapture(); + } + + @Override + public Object visit(Path.CommandTreeNode path, Void ignored) { + return null; + } + + @Override + public Object visit(Path.CommandTreeNodeForCommand path, Void ignored) { + return path.getCommand(); + } + + @Override + public Object visit(Path.Context path, Void ignored) { + return path.getCapture(); + } + + @Override + public Object visit(Path.Contexts path, Void ignored) { + return path.getCapture(); + } + + @Override + public Object visit(Path.Device path, Void ignored) { + return null; + } + + @Override + public Object visit(Path.Events path, Void ignored) { + return path.getCapture(); + } + + @Override + public Object visit(Path.FramebufferObservation path, Void ignored) { + return path.getCommand(); + } + + @Override + public Object visit(Path.Field path, Void ignored) { + switch (path.getStructCase()) { + case STATE: + return path.getState(); + case GLOBAL_STATE: + return path.getGlobalState(); + case FIELD: + return path.getField(); + case ARRAY_INDEX: + return path.getArrayIndex(); + case SLICE: + return path.getSlice(); + case MAP_INDEX: + return path.getMapIndex(); + default: + return null; + } + } + + @Override + public Object visit(Path.GlobalState path, Void ignored) { + return path.getAfter(); + } + + @Override + public Object visit(Path.ID path, Void ignored) { + return null; + } + + @Override + public Object visit(Path.ImageInfo path, Void ignored) { + return null; + } + + @Override + public Object visit(Path.MapIndex path, Void ignored) { + switch (path.getMapCase()) { + case STATE: + return path.getState(); + case FIELD: + return path.getField(); + case ARRAY_INDEX: + return path.getArrayIndex(); + case SLICE: + return path.getSlice(); + case MAP_INDEX: + return path.getMapIndex(); + default: + return null; + } + } + + @Override + public Object visit(Path.Memory path, Void ignored) { + return path.getAfter(); + } + + @Override + public Object visit(Path.Mesh path, Void ignored) { + switch (path.getObjectCase()) { + case COMMAND: + return path.getCommand(); + case COMMAND_TREE_NODE: + return path.getCommandTreeNode(); + default: + return null; + } + } + + @Override + public Object visit(Path.Parameter path, Void ignored) { + return path.getCommand(); + } + + @Override + public Object visit(Path.Report path, Void ignored) { + return path.getCapture(); + } + + @Override + public Object visit(Path.ResourceData path, Void ignored) { + return path.getAfter(); + } + + @Override + public Object visit(Path.Resources path, Void ignored) { + return path.getCapture(); + } + + @Override + public Object visit(Path.Result path, Void ignored) { + return path.getCommand(); + } + + @Override + public Object visit(Path.Slice path, Void ignored) { + switch (path.getArrayCase()) { + case FIELD: + return path.getField(); + case ARRAY_INDEX: + return path.getArrayIndex(); + case SLICE: + return path.getSlice(); + case MAP_INDEX: + return path.getMapIndex(); + default: + return null; + } + } + + @Override + public Object visit(Path.State path, Void ignored) { + return path.getAfter(); + } + + @Override + public Object visit(Path.StateTree path, Void ignored) { + return path.getState(); + } + + @Override + public Object visit(Path.StateTreeNode path, Void ignored) { + return null; + } + + @Override + public Object visit(Path.StateTreeNodeForPath path, Void ignored) { + return null; + } + + @Override + public Object visit(Path.Thumbnail path, Void ignored) { + switch (path.getObjectCase()) { + case RESOURCE: + return path.getResource(); + case COMMAND: + return path.getCommand(); + case COMMAND_TREE_NODE: + return path.getCommandTreeNode(); + default: + return null; + } + } + }; + + /** + * {@link Visitor} that returns the a copy of the provided path node, but with the parent changed + * to the specified parent node. + * Used by {@link #setParent(Object, Object)}. + */ + private static final Visitor SET_PARENT_VISITOR = new Visitor() { + @Override + public Object visit(Image.ID path, Object parent) { + throw new RuntimeException("Image.ID has no parent to set"); + } + + @Override + public Object visit(Path.API path, Object parent) { + throw new RuntimeException("Path.API has no parent to set"); + } + + @Override + public Object visit(Path.ArrayIndex path, Object parent) { + if (parent instanceof Path.Field) { + return path.toBuilder().setField((Path.Field) parent).build(); + } else if (parent instanceof Path.ArrayIndex) { + return path.toBuilder().setArrayIndex((Path.ArrayIndex) parent).build(); + } else if (parent instanceof Path.Slice) { + return path.toBuilder().setSlice((Path.Slice) parent).build(); + } else if (parent instanceof Path.MapIndex) { + return path.toBuilder().setMapIndex((Path.MapIndex) parent).build(); + } else { + throw new RuntimeException("Path.ArrayIndex cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.As path, Object parent) { + if (parent instanceof Path.Field) { + return path.toBuilder().setField((Path.Field) parent).build(); + } else if (parent instanceof Path.ArrayIndex) { + return path.toBuilder().setArrayIndex((Path.ArrayIndex) parent).build(); + } else if (parent instanceof Path.Slice) { + return path.toBuilder().setSlice((Path.Slice) parent).build(); + } else if (parent instanceof Path.MapIndex) { + return path.toBuilder().setMapIndex((Path.MapIndex) parent).build(); + } else if (parent instanceof Path.ImageInfo) { + return path.toBuilder().setImageInfo((Path.ImageInfo) parent).build(); + } else if (parent instanceof Path.ResourceData) { + return path.toBuilder().setResourceData((Path.ResourceData) parent).build(); + } else if (parent instanceof Path.Mesh) { + return path.toBuilder().setMesh((Path.Mesh) parent).build(); + } else { + throw new RuntimeException("Path.As cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Blob path, Object parent) { + throw new RuntimeException("Path.Blob has no parent to set"); + } + + @Override + public Object visit(Path.Capture path, Object parent) { + throw new RuntimeException("Path.Capture has no parent to set"); + } + + @Override + public Object visit(Path.ConstantSet path, Object parent) { + if (parent instanceof Path.API) { + return path.toBuilder().setApi((Path.API) parent).build(); + } else { + throw new RuntimeException("Path.ConstantSet cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Command path, Object parent) { + if (parent instanceof Path.Capture) { + return path.toBuilder().setCapture((Path.Capture) parent).build(); + } else { + throw new RuntimeException("Path.Command cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Commands path, Object parent) { + if (parent instanceof Path.Capture) { + return path.toBuilder().setCapture((Path.Capture) parent).build(); + } else { + throw new RuntimeException("Path.Commands cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.CommandTree path, Object parent) { + if (parent instanceof Path.Capture) { + return path.toBuilder().setCapture((Path.Capture) parent).build(); + } else { + throw new RuntimeException("Path.CommandTree cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.CommandTreeNode path, Object parent) { + throw new RuntimeException("Path.CommandTreeNode has no parent to set"); + } + + @Override + public Object visit(Path.CommandTreeNodeForCommand path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setCommand((Path.Command) parent).build(); + } else { + throw new RuntimeException("Path.CommandTreeNodeForCommand cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Context path, Object parent) { + if (parent instanceof Path.Capture) { + return path.toBuilder().setCapture((Path.Capture) parent).build(); + } else { + throw new RuntimeException("Path.Context cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Contexts path, Object parent) { + if (parent instanceof Path.Capture) { + return path.toBuilder().setCapture((Path.Capture) parent).build(); + } else { + throw new RuntimeException("Path.Contexts cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Device path, Object parent) { + throw new RuntimeException("Path.Device has no parent to set"); + } + + @Override + public Object visit(Path.Events path, Object parent) { + if (parent instanceof Path.Capture) { + return path.toBuilder().setCapture((Path.Capture) parent).build(); + } else { + throw new RuntimeException("Path.Events cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.FramebufferObservation path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setCommand((Path.Command) parent).build(); + } else { + throw new RuntimeException("Path.FramebufferObservation cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Field path, Object parent) { + if (parent instanceof Path.State) { + return path.toBuilder().setState((Path.State) parent).build(); + } else if (parent instanceof Path.GlobalState) { + return path.toBuilder().setGlobalState((Path.GlobalState) parent).build(); + } else if (parent instanceof Path.Field) { + return path.toBuilder().setField((Path.Field) parent).build(); + } else if (parent instanceof Path.ArrayIndex) { + return path.toBuilder().setArrayIndex((Path.ArrayIndex) parent).build(); + } else if (parent instanceof Path.Slice) { + return path.toBuilder().setSlice((Path.Slice) parent).build(); + } else if (parent instanceof Path.MapIndex) { + return path.toBuilder().setMapIndex((Path.MapIndex) parent).build(); + } else { + throw new RuntimeException("Path.Field cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.GlobalState path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setAfter((Path.Command) parent).build(); + } else { + throw new RuntimeException("Path.GlobalState cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.ID path, Object parent) { + throw new RuntimeException("Path.ID has no parent to set"); + } + + @Override + public Object visit(Path.ImageInfo path, Object parent) { + throw new RuntimeException("Path.ImageInfo has no parent to set"); + } + + @Override + public Object visit(Path.MapIndex path, Object parent) { + if (parent instanceof Path.State) { + return path.toBuilder().setState((Path.State) parent).build(); + } else if (parent instanceof Path.Field) { + return path.toBuilder().setField((Path.Field) parent).build(); + } else if (parent instanceof Path.ArrayIndex) { + return path.toBuilder().setArrayIndex((Path.ArrayIndex) parent).build(); + } else if (parent instanceof Path.Slice) { + return path.toBuilder().setSlice((Path.Slice) parent).build(); + } else if (parent instanceof Path.MapIndex) { + return path.toBuilder().setMapIndex((Path.MapIndex) parent).build(); + } else { + throw new RuntimeException("Path.MapIndex cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Memory path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setAfter((Path.Command) parent).build(); + } else { + throw new RuntimeException("Path.Memory cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Mesh path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setCommand((Path.Command) parent).build(); + } else if (parent instanceof Path.CommandTreeNode) { + return path.toBuilder().setCommandTreeNode((Path.CommandTreeNode) parent).build(); + } else { + throw new RuntimeException("Path.Mesh cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Parameter path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setCommand((Path.Command) parent).build(); + } else { + throw new RuntimeException("Path.Parameter cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Report path, Object parent) { + if (parent instanceof Path.Capture) { + return path.toBuilder().setCapture((Path.Capture) parent).build(); + } else { + throw new RuntimeException("Path.Report cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.ResourceData path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setAfter((Path.Command) parent).build(); + } else { + throw new RuntimeException("Path.ResourceData cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Resources path, Object parent) { + if (parent instanceof Path.Capture) { + return path.toBuilder().setCapture((Path.Capture) parent).build(); + } else { + throw new RuntimeException("Path.Resources cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Result path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setCommand((Path.Command) parent).build(); + } else { + throw new RuntimeException("Path.Result cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.Slice path, Object parent) { + if (parent instanceof Path.Field) { + return path.toBuilder().setField((Path.Field) parent).build(); + } else if (parent instanceof Path.ArrayIndex) { + return path.toBuilder().setArrayIndex((Path.ArrayIndex) parent).build(); + } else if (parent instanceof Path.Slice) { + return path.toBuilder().setSlice((Path.Slice) parent).build(); + } else if (parent instanceof Path.MapIndex) { + return path.toBuilder().setMapIndex((Path.MapIndex) parent).build(); + } else { + throw new RuntimeException("Path.Slice cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.State path, Object parent) { + if (parent instanceof Path.Command) { + return path.toBuilder().setAfter((Path.Command) parent).build(); + } else { + throw new RuntimeException("Path.State cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.StateTree path, Object parent) { + if (parent instanceof Path.State) { + return path.toBuilder().setState((Path.State) parent).build(); + } else { + throw new RuntimeException("Path.StateTree cannot set parent to " + parent.getClass().getName()); + } + } + + @Override + public Object visit(Path.StateTreeNode path, Object parent) { + throw new RuntimeException("Path.StateTreeNode has no parent to set"); + } + + @Override + public Object visit(Path.StateTreeNodeForPath path, Object parent) { + throw new RuntimeException("Path.StateTreeNodeForPath has no parent to set"); + } + + @Override + public Object visit(Path.Thumbnail path, Object parent) { + if (parent instanceof Path.ResourceData) { + return path.toBuilder().setResource((Path.ResourceData) parent).build(); + } else if (parent instanceof Path.Command) { + return path.toBuilder().setCommand((Path.Command) parent).build(); + } else if (parent instanceof Path.CommandTreeNode) { + return path.toBuilder().setCommandTreeNode((Path.CommandTreeNode) parent).build(); + } else { + throw new RuntimeException("Path.Thumbnail cannot set parent to " + parent.getClass().getName()); + } + } + }; + + /** + * {@link Visitor} that prints the path to the provided {@link StringBuilder}, then returns that + * {@link StringBuilder}. + * Used by {@link #toString(Object)}. + */ + private static final Visitor PRINT_VISITOR = new Visitor() { + @Override + public StringBuilder visit(Image.ID path, StringBuilder sb) { + return sb.append(ProtoDebugTextFormat.shortDebugString(path)); + } + + @Override + public StringBuilder visit(Path.API path, StringBuilder sb) { + sb.append("API{"); + visit(path.getId(), sb); + sb.append("}"); + return sb; + } + + @Override + public StringBuilder visit(Path.ArrayIndex path, StringBuilder sb) { + return dispatch(parentOf(path), this, sb) + .append("[") + .append(UnsignedLongs.toString(path.getIndex())) + .append("]"); + } + + @Override + public StringBuilder visit(Path.As path, StringBuilder sb) { + dispatch(parentOf(path), this, sb); + switch (path.getToCase()) { + case IMAGE_FORMAT: + sb.append(".as("); + sb.append(path.getImageFormat().getName()); // TODO + sb.append(")"); + case VERTEX_BUFFER_FORMAT: + sb.append(".as(VBF)"); // TODO + default: + sb.append(".as(??)"); + } + return sb; + } + + @Override + public StringBuilder visit(Path.Blob path, StringBuilder sb) { + sb.append("blob{"); + visit(path.getId(), sb); + sb.append("}"); + return sb; + } + + @Override + public StringBuilder visit(Path.Capture path, StringBuilder sb) { + sb.append("capture{"); + visit(path.getId(), sb); + sb.append("}"); + return sb; + } + + @Override + public StringBuilder visit(Path.ConstantSet path, StringBuilder sb) { + return visit(path.getApi(), sb) + .append(".constants[") + .append(path.getIndex()) + .append("]"); + } + + @Override + public StringBuilder visit(Path.Command path, StringBuilder sb) { + return visit(path.getCapture(), sb) + .append(".command[") + .append(Formatter.atomIndex(path)) + .append("]"); + } + + @Override + public StringBuilder visit(Path.Commands path, StringBuilder sb) { + return visit(path.getCapture(), sb) + .append(".command[") + .append(Formatter.firstIndex(path)) + .append(":") + .append(Formatter.lastIndex(path)) + .append("]"); + } + + @Override + public StringBuilder visit(Path.CommandTree path, StringBuilder sb) { + visit(path.getCapture(), sb) + .append(".tree"); + append(sb, path.getFilter()).append('['); + if (path.getGroupByApi()) sb.append('A'); + if (path.getGroupByThread()) sb.append('T'); + if (path.getGroupByContext()) sb.append('C'); + if (path.getIncludeNoContextGroups()) sb.append('n'); + if (path.getGroupByFrame()) sb.append('F'); + if (path.getAllowIncompleteFrame()) sb.append('i'); + if (path.getGroupByDrawCall()) sb.append('D'); + if (path.getGroupByUserMarkers()) sb.append('M'); + if (path.getMaxChildren() != 0) { + sb.append(",max=").append(path.getMaxChildren()); + } + sb.append(']'); + return sb; + } + + @Override + public StringBuilder visit(Path.CommandTreeNode path, StringBuilder sb) { + sb.append("tree{"); + visit(path.getTree(), sb); + sb.append("}.node("); + sb.append(Formatter.index(path.getIndicesList())); + sb.append(")"); + return sb; + } + + @Override + public StringBuilder visit(Path.CommandTreeNodeForCommand path, StringBuilder sb) { + sb.append("tree{"); + visit(path.getTree(), sb); + sb.append("}.command("); + visit(path.getCommand(), sb); + sb.append(")"); + return sb; + } + + @Override + public StringBuilder visit(Path.Context path, StringBuilder sb) { + visit(path.getCapture(), sb); + sb.append(".context["); + visit(path.getId(), sb); + sb.append("]"); + return sb; + } + + @Override + public StringBuilder visit(Path.Contexts path, StringBuilder sb) { + return visit(path.getCapture(), sb).append(".contexts"); + } + + @Override + public StringBuilder visit(Path.Device path, StringBuilder sb) { + sb.append("device{"); + visit(path.getId(), sb); + sb.append("}"); + return sb; + } + + @Override + public StringBuilder visit(Path.Events path, StringBuilder sb) { + visit(path.getCapture(), sb).append(".events"); + append(sb, path.getFilter()).append('['); + if (path.getFirstInFrame()) sb.append("Fs"); + if (path.getLastInFrame()) sb.append("Fe"); + if (path.getClears()) sb.append("C"); + if (path.getDrawCalls()) sb.append("D"); + if (path.getUserMarkers()) sb.append("M"); + if (path.getPushUserMarkers()) sb.append("Ms"); + if (path.getPopUserMarkers()) sb.append("Me"); + if (path.getFramebufferObservations()) sb.append("O"); + return sb.append(']'); + } + + @Override + public StringBuilder visit(Path.FramebufferObservation path, StringBuilder sb) { + return visit(path.getCommand(), sb).append(".fbo"); + } + + @Override + public StringBuilder visit(Path.Field path, StringBuilder sb) { + return dispatch(parentOf(path), this, sb) + .append(".") + .append(path.getName()); + } + + @Override + public StringBuilder visit(Path.GlobalState path, StringBuilder sb) { + return visit(path.getAfter(), sb).append(".global-state"); + } + + @Override + public StringBuilder visit(Path.ID path, StringBuilder sb) { + return sb.append(ProtoDebugTextFormat.shortDebugString(path)); + } + + @Override + public StringBuilder visit(Path.ImageInfo path, StringBuilder sb) { + sb.append("image{"); + visit(path.getId(), sb); + sb.append("}"); + return sb; + } + + @Override + public StringBuilder visit(Path.MapIndex path, StringBuilder sb) { + dispatch(parentOf(path), this, sb); + switch (path.getKeyCase()) { + case BOX: + return sb.append("[").append(Formatter.toString(path.getBox(), null, true)).append("]"); + default: + return sb.append("[??]"); + } + } + + @Override + public StringBuilder visit(Path.Memory path, StringBuilder sb) { + visit(path.getAfter(), sb) + .append(".memory(") + .append("pool:").append(path.getPool()).append(',') + .append(Long.toHexString(path.getAddress())).append('[').append(path.getSize()).append(']'); + if (path.getExcludeData()) sb.append(",nodata"); + if (path.getExcludeObserved()) sb.append(",noobs"); + return sb.append(')'); + } + + @Override + public StringBuilder visit(Path.Mesh path, StringBuilder sb) { + visit(path.getCommand(), sb).append(".mesh("); + if (path.getOptions().getFaceted()) sb.append("faceted"); + return sb.append(')'); + } + + @Override + public StringBuilder visit(Path.Parameter path, StringBuilder sb) { + return visit(path.getCommand(), sb).append(".").append(path.getName()); + } + + @Override + public StringBuilder visit(Path.Report path, StringBuilder sb) { + visit(path.getCapture(), sb).append(".report"); + if (path.hasDevice()) { + sb.append('['); + visit(path.getDevice(), sb); + sb.append(']'); + } + return append(sb, path.getFilter()); + } + + @Override + public StringBuilder visit(Path.ResourceData path, StringBuilder sb) { + visit(path.getAfter(), sb).append(".resource{"); + visit(path.getId(), sb).append("}"); + return sb; + } + + @Override + public StringBuilder visit(Path.Resources path, StringBuilder sb) { + return visit(path.getCapture(), sb).append(".resources"); + } + + @Override + public StringBuilder visit(Path.Result path, StringBuilder sb) { + return visit(path.getCommand(), sb).append("."); + } + + @Override + public StringBuilder visit(Path.Slice path, StringBuilder sb) { + return dispatch(parentOf(path), this, sb) + .append("[") + .append(path.getStart()) + .append(":") + .append(path.getEnd()) + .append("]"); + } + + @Override + public StringBuilder visit(Path.State path, StringBuilder sb) { + return visit(path.getAfter(), sb).append(".state"); + } + + @Override + public StringBuilder visit(Path.StateTree path, StringBuilder sb) { + visit(path.getState(), sb).append(".tree"); + if (path.getArrayGroupSize() > 0) { + sb.append("(groupSize=").append(path.getArrayGroupSize()).append(')'); + } + return sb; + } + + @Override + public StringBuilder visit(Path.StateTreeNode path, StringBuilder sb) { + sb.append("stateTree{"); + visit(path.getTree(), sb); + return sb.append("}.node(") + .append(Formatter.index(path.getIndicesList())) + .append(")"); + } + + @Override + public StringBuilder visit(Path.StateTreeNodeForPath path, StringBuilder sb) { + sb.append("stateTree{"); + visit(path.getTree(), sb); + return sb.append("}.path(") + .append(Paths.toString(path.getMember())) + .append(")"); + } + + @Override + public StringBuilder visit(Path.Thumbnail path, StringBuilder sb) { + dispatch(parentOf(path), this, sb) + .append(".thumbnail"); + String sep = "(", end = ""; + if (path.getDesiredMaxWidth() > 0) { + sb.append(sep).append("w=").append(path.getDesiredMaxWidth()); + sep = ","; + end = ")"; + } + if (path.getDesiredMaxHeight() > 0) { + sb.append(sep).append("h=").append(path.getDesiredMaxHeight()); + sep = ","; + end = ")"; + } + if (path.hasDesiredFormat()) { + sb.append(sep).append("f=").append(path.getDesiredFormat().getName()); // TODO + sep = ","; + end = ")"; + } + return sb.append(end); + } + + private StringBuilder append(StringBuilder sb, Path.CommandFilter filter) { + String sep = "(", end = ""; + if (filter.hasContext()) { + sb.append(sep).append("context="); + visit(filter.getContext(), sb); + sep = ","; + end = ")"; + } + if (filter.getThreadsCount() > 0) { + sb.append(sep).append("threads=").append(filter.getThreadsList()); + sep = ","; + end = ")"; + } + return sb.append(end); + } + }; } diff --git a/gapic/src/main/com/google/gapid/views/AtomEditor.java b/gapic/src/main/com/google/gapid/views/AtomEditor.java index 5e0029019d..02d62f18f3 100644 --- a/gapic/src/main/com/google/gapid/views/AtomEditor.java +++ b/gapic/src/main/com/google/gapid/views/AtomEditor.java @@ -92,7 +92,7 @@ public static boolean shouldShowEditPopup(API.Command command) { public void showEditPopup(Shell parent, Path.Command path, API.Command command) { EditDialog dialog = new EditDialog(parent, models, command); if (dialog.open() == Window.OK) { - Rpc.listen(client.set(Paths.any(path), Values.value(dialog.newAtom)), + Rpc.listen(client.set(Paths.toAny(path), Values.value(dialog.newAtom)), new UiCallback(parent, LOG) { @Override protected Path.Any onRpcThread(Rpc.Result result) diff --git a/gapic/src/main/com/google/gapid/views/StateView.java b/gapic/src/main/com/google/gapid/views/StateView.java index 890e8b29c7..30caedadfc 100644 --- a/gapic/src/main/com/google/gapid/views/StateView.java +++ b/gapic/src/main/com/google/gapid/views/StateView.java @@ -37,6 +37,7 @@ import com.google.gapid.models.Models; import com.google.gapid.proto.service.Service; import com.google.gapid.proto.service.path.Path; +import com.google.gapid.proto.service.path.Path.GlobalState; import com.google.gapid.rpc.Rpc; import com.google.gapid.rpc.RpcException; import com.google.gapid.rpc.UiCallback; @@ -370,11 +371,11 @@ private List getExpandedPaths() { } protected void updateExpansionState(List paths, int retry) { - Path.State state = Paths.stateAfter(models.state.getSource().getStateTree().getAfter()); ApiState.Node root = models.state.getData(); + GlobalState rootPath = Paths.findGlobalState(root.getData().getValuePath()); List> futures = Lists.newArrayList(); for (Path.Any path : paths) { - Path.Any reparented = Paths.reparent(path, state); + Path.Any reparented = Paths.reparent(path, rootPath); if (reparented == null) { LOG.log(WARNING, "Unable to reparent path {0}", path); continue; diff --git a/gapis/api/api.go b/gapis/api/api.go index 5e873bc5d4..809fd4b2d8 100644 --- a/gapis/api/api.go +++ b/gapis/api/api.go @@ -40,10 +40,10 @@ type API interface { // specified framebuffer attachment. // It also returns an API specific index that maps the given attachment into // an API specific representation. - GetFramebufferAttachmentInfo(state *State, thread uint64, attachment FramebufferAttachment) (width, height uint32, index uint32, format *image.Format, err error) + GetFramebufferAttachmentInfo(state *GlobalState, thread uint64, attachment FramebufferAttachment) (width, height uint32, index uint32, format *image.Format, err error) // Context returns the active context for the given state. - Context(state *State, thread uint64) Context + Context(state *GlobalState, thread uint64) Context // CreateCmd constructs and returns a new command with the specified name. CreateCmd(name string) Cmd @@ -52,15 +52,16 @@ type API interface { // ID is an API identifier type ID id.ID +// IsValid returns true if the id is not the default zero value. +func (i ID) IsValid() bool { return id.ID(i).IsValid() } +func (i ID) String() string { return id.ID(i).String() } + // APIObject is the interface implemented by types that belong to an API. type APIObject interface { // API returns the API identifier that this type belongs to. API() API } -// IsValid returns true if the id is not the default zero value. -func (i ID) IsValid() bool { return id.ID(i).IsValid() } - var apis = map[ID]API{} var indices = map[uint8]bool{} diff --git a/gapis/api/cmd.go b/gapis/api/cmd.go index d524268627..ae1a3aefab 100644 --- a/gapis/api/cmd.go +++ b/gapis/api/cmd.go @@ -45,14 +45,14 @@ type Cmd interface { CmdName() string // CmdFlags returns the flags of the command. - CmdFlags(context.Context, CmdID, *State) CmdFlags + CmdFlags(context.Context, CmdID, *GlobalState) CmdFlags // Extras returns all the Extras associated with the dynamic command. Extras() *CmdExtras // Mutate mutates the State using the command. If the builder argument is // not nil then it will call the replay function on the builder. - Mutate(context.Context, CmdID, *State, *builder.Builder) error + Mutate(context.Context, CmdID, *GlobalState, *builder.Builder) error } const ( diff --git a/gapis/api/cmd_foreach.go b/gapis/api/cmd_foreach.go index 4f0bb8cfe1..1bf26f797f 100644 --- a/gapis/api/cmd_foreach.go +++ b/gapis/api/cmd_foreach.go @@ -58,7 +58,7 @@ func ForeachCmd(ctx context.Context, cmds []Cmd, cb func(context.Context, CmdID, } // MutateCmds calls Mutate on each of cmds. -func MutateCmds(ctx context.Context, state *State, builder *builder.Builder, cmds ...Cmd) { +func MutateCmds(ctx context.Context, state *GlobalState, builder *builder.Builder, cmds ...Cmd) { ForeachCmd(ctx, cmds, func(ctx context.Context, id CmdID, cmd Cmd) error { cmd.Mutate(ctx, id, state, builder) return nil diff --git a/gapis/api/gles/compat.go b/gapis/api/gles/compat.go index bc4c6fa971..f113bb72b6 100644 --- a/gapis/api/gles/compat.go +++ b/gapis/api/gles/compat.go @@ -983,7 +983,7 @@ func compat(ctx context.Context, device *device.Instance) (transform.Transformer case *EglCreateImageKHR: { - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { return cmd.Mutate(ctx, id, s, nil) // do not call, just mutate })) @@ -1004,7 +1004,7 @@ func compat(ctx context.Context, device *device.Instance) (transform.Transformer textureCompat.convertFormat(ctx, GLenum_GL_TEXTURE_2D, &sizedFormat, nil, nil, out, id, cmd) out.MutateAndWrite(ctx, dID, cb.GlTexImage2D(GLenum_GL_TEXTURE_2D, 0, GLint(sizedFormat), img.Width, img.Height, 0, img.DataFormat, img.DataType, memory.Nullptr)) - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { GetState(s).EGLImages[cmd.Result].TargetContext = c.Identifier GetState(s).EGLImages[cmd.Result].TargetTexture = texId return nil @@ -1018,7 +1018,7 @@ func compat(ctx context.Context, device *device.Instance) (transform.Transformer { cmd := *cmd convertTexTarget(&cmd.Target) - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { return cmd.Mutate(ctx, id, s, nil) // do not call, just mutate })) @@ -1051,7 +1051,7 @@ func compat(ctx context.Context, device *device.Instance) (transform.Transformer cmd.Mutate(ctx, id, s, nil /* no builder, just mutate */) // Translate it to the non-multiview version, but do not modify state, // otherwise we would lose the knowledge about view count. - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { cb.GlFramebufferTextureLayer(cmd.Target, cmd.Attachment, cmd.Texture, cmd.Level, cmd.BaseViewIndex).Call(ctx, s, b) return nil })) @@ -1064,7 +1064,7 @@ func compat(ctx context.Context, device *device.Instance) (transform.Transformer cmd.Mutate(ctx, id, s, nil /* no builder, just mutate */) // Translate it to the non-multiview version, but do not modify state, // otherwise we would lose the knowledge about view count. - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { cb.GlFramebufferTextureLayer(cmd.Target, cmd.Attachment, cmd.Texture, cmd.Level, cmd.BaseViewIndex).Call(ctx, s, b) return nil })) @@ -1131,7 +1131,7 @@ func compatMultiviewDraw(ctx context.Context, id api.CmdID, cmd api.Cmd, out tra for viewID := GLuint(0); viewID < GLuint(numViews); viewID++ { // Set the magic uniform which shaders use to fetch view-dependent attributes. // It is missing from the observed extras, so normal mutation would fail. - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { if c.Bound.Program != nil { viewIDLocation := UniformLocation(0x7FFF0000) cb.GlGetUniformLocation(c.Bound.Program.ID, "gapid_gl_ViewID_OVR", viewIDLocation).Call(ctx, s, b) @@ -1143,7 +1143,7 @@ func compatMultiviewDraw(ctx context.Context, id api.CmdID, cmd api.Cmd, out tra // For each attachment, bind the layer corresponding to this ViewID. // Do not modify the state so that we do not revert to single-view for next draw call. c.Bound.DrawFramebuffer.ForEachAttachment(func(name GLenum, a FramebufferAttachment) { - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { if a.Texture != nil { cb.GlFramebufferTextureLayer(GLenum_GL_DRAW_FRAMEBUFFER, name, a.Texture.ID, a.TextureLevel, a.TextureLayer+GLint(viewID)).Call(ctx, s, b) } diff --git a/gapis/api/gles/compat_client.go b/gapis/api/gles/compat_client.go index 6c8d32b1c1..a1c37ede3f 100644 --- a/gapis/api/gles/compat_client.go +++ b/gapis/api/gles/compat_client.go @@ -76,7 +76,7 @@ func compatDrawElements( clientVAs map[*VertexAttributeArray]*GlVertexAttribPointer, id api.CmdID, cmd drawElements, - s *api.State, + s *api.GlobalState, out transform.Writer) { c := GetContext(s, cmd.Thread()) @@ -161,7 +161,7 @@ func moveClientVBsToVAs( first, count uint32, // vertex indices id api.CmdID, cmd api.Cmd, - s *api.State, + s *api.GlobalState, c *Context, out transform.Writer) { @@ -207,7 +207,7 @@ func moveClientVBsToVAs( // Apply the memory observations that were made by the draw call now. // We need to do this as the glBufferData calls below will require the data. dID := id.Derived() - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { cmd.Extras().Observations().ApplyReads(s.Memory.ApplicationPool()) return nil })) diff --git a/gapis/api/gles/compat_test.go b/gapis/api/gles/compat_test.go index 0459096a3a..80740d83e2 100644 --- a/gapis/api/gles/compat_test.go +++ b/gapis/api/gles/compat_test.go @@ -43,7 +43,7 @@ func p(addr uint64) memory.Pointer { type glShaderSourceCompatTest glslCompatTest -func newState(ctx context.Context) *api.State { +func newState(ctx context.Context) *api.GlobalState { s, err := capture.NewState(ctx) if err != nil { panic(err) diff --git a/gapis/api/gles/context.go b/gapis/api/gles/context.go index bd2d7515fe..9a14f41b9f 100644 --- a/gapis/api/gles/context.go +++ b/gapis/api/gles/context.go @@ -32,7 +32,10 @@ func (c *Context) Name() string { // ID returns the context's unique identifier. func (c *Context) ID() api.ContextID { - return api.ContextID(id.OfString(c.Name())) + if c == nil { + return api.ContextID{} + } + return api.ContextID(id.OfString(fmt.Sprintf("GLES Context %v", c.Identifier))) } // API returns the GLES API. diff --git a/gapis/api/gles/custom_replay.go b/gapis/api/gles/custom_replay.go index c0187774fe..4d5647192e 100644 --- a/gapis/api/gles/custom_replay.go +++ b/gapis/api/gles/custom_replay.go @@ -35,7 +35,7 @@ type objectKey struct { mapKey interface{} } -func (i BufferId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i BufferId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.Shared.Buffers, i}, true @@ -43,7 +43,7 @@ func (i BufferId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) return } -func (i FramebufferId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i FramebufferId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.Framebuffers, i}, true @@ -51,7 +51,7 @@ func (i FramebufferId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap return } -func (i RenderbufferId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i RenderbufferId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.Shared.Renderbuffers, i}, true @@ -59,7 +59,7 @@ func (i RenderbufferId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap return } -func (i ProgramId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i ProgramId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.Shared.Programs, i}, true @@ -67,7 +67,7 @@ func (i ProgramId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool return } -func (i ShaderId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i ShaderId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.Shared.Shaders, i}, true @@ -75,7 +75,7 @@ func (i ShaderId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) return } -func (i TextureId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i TextureId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { if tex := ctx.Objects.Shared.Textures[i]; tex != nil { @@ -100,7 +100,7 @@ func (i TextureId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool return } -func (i UniformBlockIndex) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i UniformBlockIndex) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) program := ctx.Bound.Program.GetID() switch cmd := cmd.(type) { @@ -119,7 +119,7 @@ func (i UniformBlockIndex) remap(cmd api.Cmd, s *api.State) (key interface{}, re }{ctx.Objects.Shared.Programs[program], i}, true } -func (i VertexArrayId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i VertexArrayId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.VertexArrays, i}, true @@ -127,7 +127,7 @@ func (i VertexArrayId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap return } -func (i QueryId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i QueryId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.Queries, i}, true @@ -135,7 +135,7 @@ func (i QueryId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) return } -func (i GLsync) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i GLsync) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && !i.IsNullptr() { key, remap = objectKey{&ctx.Objects.Shared.SyncObjects, i}, true @@ -143,11 +143,11 @@ func (i GLsync) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { return } -func (i GLsync) value(b *builder.Builder, cmd api.Cmd, s *api.State) value.Value { +func (i GLsync) value(b *builder.Builder, cmd api.Cmd, s *api.GlobalState) value.Value { return value.AbsolutePointer(i.addr) } -func (i SamplerId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i SamplerId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.Shared.Samplers, i}, true @@ -155,7 +155,7 @@ func (i SamplerId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool return } -func (i PipelineId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i PipelineId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.Pipelines, i}, true @@ -163,7 +163,7 @@ func (i PipelineId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap boo return } -func (i TransformFeedbackId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i TransformFeedbackId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && i != 0 { key, remap = objectKey{&ctx.Objects.TransformFeedbacks, i}, true @@ -171,7 +171,7 @@ func (i TransformFeedbackId) remap(cmd api.Cmd, s *api.State) (key interface{}, return } -func (i UniformLocation) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i UniformLocation) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) program := ctx.Bound.Program.GetID() switch cmd := cmd.(type) { @@ -186,7 +186,7 @@ func (i UniformLocation) remap(cmd api.Cmd, s *api.State) (key interface{}, rema }{ctx.Objects.Shared.Programs[program], i}, true } -func (i SrcImageId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i SrcImageId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { switch cmd := cmd.(type) { case *GlCopyImageSubData: return remapImageId(cmd, s, GLuint(cmd.SrcName), cmd.SrcTarget) @@ -199,7 +199,7 @@ func (i SrcImageId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap boo } } -func (i DstImageId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap bool) { +func (i DstImageId) remap(cmd api.Cmd, s *api.GlobalState) (key interface{}, remap bool) { switch cmd := cmd.(type) { case *GlCopyImageSubData: return remapImageId(cmd, s, GLuint(cmd.DstName), cmd.DstTarget) @@ -212,7 +212,7 @@ func (i DstImageId) remap(cmd api.Cmd, s *api.State) (key interface{}, remap boo } } -func remapImageId(cmd api.Cmd, s *api.State, name GLuint, target GLenum) (key interface{}, remap bool) { +func remapImageId(cmd api.Cmd, s *api.GlobalState, name GLuint, target GLenum) (key interface{}, remap bool) { ctx := GetContext(s, cmd.Thread()) if ctx != nil && name != 0 { if target == GLenum_GL_RENDERBUFFER { @@ -224,7 +224,7 @@ func remapImageId(cmd api.Cmd, s *api.State, name GLuint, target GLenum) (key in return } -func (i IndicesPointer) value(b *builder.Builder, cmd api.Cmd, s *api.State) value.Value { +func (i IndicesPointer) value(b *builder.Builder, cmd api.Cmd, s *api.GlobalState) value.Value { c := GetContext(s, cmd.Thread()) if c.Bound.VertexArray.ElementArrayBuffer != nil { return value.AbsolutePointer(i.addr) @@ -233,7 +233,7 @@ func (i IndicesPointer) value(b *builder.Builder, cmd api.Cmd, s *api.State) val } } -func (i VertexPointer) value(b *builder.Builder, cmd api.Cmd, s *api.State) value.Value { +func (i VertexPointer) value(b *builder.Builder, cmd api.Cmd, s *api.GlobalState) value.Value { c := GetContext(s, cmd.Thread()) if c.Bound.ArrayBuffer != nil { return value.AbsolutePointer(i.addr) @@ -242,7 +242,7 @@ func (i VertexPointer) value(b *builder.Builder, cmd api.Cmd, s *api.State) valu } } -func (i TexturePointer) value(b *builder.Builder, cmd api.Cmd, s *api.State) value.Value { +func (i TexturePointer) value(b *builder.Builder, cmd api.Cmd, s *api.GlobalState) value.Value { if i.addr == 0 || GetContext(s, cmd.Thread()).Bound.PixelUnpackBuffer != nil { return value.AbsolutePointer(i.addr) } else { @@ -250,7 +250,7 @@ func (i TexturePointer) value(b *builder.Builder, cmd api.Cmd, s *api.State) val } } -func (i BufferDataPointer) value(b *builder.Builder, cmd api.Cmd, s *api.State) value.Value { +func (i BufferDataPointer) value(b *builder.Builder, cmd api.Cmd, s *api.GlobalState) value.Value { if i.addr == 0 { return value.AbsolutePointer(i.addr) } else { @@ -258,11 +258,11 @@ func (i BufferDataPointer) value(b *builder.Builder, cmd api.Cmd, s *api.State) } } -func (i GLeglImageOES) value(b *builder.Builder, cmd api.Cmd, s *api.State) value.Value { +func (i GLeglImageOES) value(b *builder.Builder, cmd api.Cmd, s *api.GlobalState) value.Value { return value.AbsolutePointer(i.addr) } -func (ω *EglCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *EglCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -272,7 +272,7 @@ func (ω *EglCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.Sta return cb.ReplayCreateRenderer(ctxID).Mutate(ctx, id, s, b) } -func (ω *EglMakeCurrent) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *EglMakeCurrent) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { prevContext := GetState(s).Contexts[ω.Thread()] _, existed := GetState(s).EGLContexts[ω.Context] err := ω.mutate(ctx, id, s, nil) @@ -314,7 +314,7 @@ func (ω *EglMakeCurrent) Mutate(ctx context.Context, id api.CmdID, s *api.State return nil } -func (ω *WglCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *WglCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -324,7 +324,7 @@ func (ω *WglCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.Sta return cb.ReplayCreateRenderer(ctxID).Mutate(ctx, id, s, b) } -func (ω *WglCreateContextAttribsARB) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *WglCreateContextAttribsARB) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -334,7 +334,7 @@ func (ω *WglCreateContextAttribsARB) Mutate(ctx context.Context, id api.CmdID, return cb.ReplayCreateRenderer(ctxID).Mutate(ctx, id, s, b) } -func (ω *WglMakeCurrent) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *WglMakeCurrent) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -347,7 +347,7 @@ func (ω *WglMakeCurrent) Mutate(ctx context.Context, id api.CmdID, s *api.State return cb.ReplayBindRenderer(ctxID).Mutate(ctx, id, s, b) } -func (ω *CGLCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *CGLCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -357,7 +357,7 @@ func (ω *CGLCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.Sta return cb.ReplayCreateRenderer(ctxID).Mutate(ctx, id, s, b) } -func (ω *CGLSetCurrentContext) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *CGLSetCurrentContext) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -370,7 +370,7 @@ func (ω *CGLSetCurrentContext) Mutate(ctx context.Context, id api.CmdID, s *api return cb.ReplayBindRenderer(ctxID).Mutate(ctx, id, s, b) } -func (ω *GlXCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *GlXCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -380,7 +380,7 @@ func (ω *GlXCreateContext) Mutate(ctx context.Context, id api.CmdID, s *api.Sta return cb.ReplayCreateRenderer(ctxID).Mutate(ctx, id, s, b) } -func (ω *GlXCreateNewContext) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *GlXCreateNewContext) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -390,7 +390,7 @@ func (ω *GlXCreateNewContext) Mutate(ctx context.Context, id api.CmdID, s *api. return cb.ReplayCreateRenderer(ctxID).Mutate(ctx, id, s, b) } -func (ω *GlXMakeContextCurrent) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (ω *GlXMakeContextCurrent) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { err := ω.mutate(ctx, id, s, nil) if b == nil || err != nil { return err @@ -404,7 +404,7 @@ func (ω *GlXMakeContextCurrent) Mutate(ctx context.Context, id api.CmdID, s *ap } // Force all attributes to use the capture-observed locations during replay. -func bindAttribLocations(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.State, b *builder.Builder, pid ProgramId) error { +func bindAttribLocations(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.GlobalState, b *builder.Builder, pid ProgramId) error { pi := FindProgramInfo(cmd.Extras()) if pi != nil && b != nil { cb := CommandBuilder{Thread: cmd.Thread()} @@ -426,7 +426,7 @@ func bindAttribLocations(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api. } // Remap uniform block indices -func bindUniformBlocks(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.State, b *builder.Builder, pid ProgramId) error { +func bindUniformBlocks(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.GlobalState, b *builder.Builder, pid ProgramId) error { pi := FindProgramInfo(cmd.Extras()) if pi != nil && b != nil { cb := CommandBuilder{Thread: cmd.Thread()} @@ -441,7 +441,7 @@ func bindUniformBlocks(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.St return nil } -func (cmd *GlProgramBinaryOES) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (cmd *GlProgramBinaryOES) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { if err := bindAttribLocations(ctx, cmd, id, s, b, cmd.Program); err != nil { return err } @@ -454,7 +454,7 @@ func (cmd *GlProgramBinaryOES) Mutate(ctx context.Context, id api.CmdID, s *api. return nil } -func (cmd *GlLinkProgram) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (cmd *GlLinkProgram) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { if err := bindAttribLocations(ctx, cmd, id, s, b, cmd.Program); err != nil { return err } @@ -467,7 +467,7 @@ func (cmd *GlLinkProgram) Mutate(ctx context.Context, id api.CmdID, s *api.State return nil } -func (cmd *GlProgramBinary) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (cmd *GlProgramBinary) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { if err := bindAttribLocations(ctx, cmd, id, s, b, cmd.Program); err != nil { return err } diff --git a/gapis/api/gles/dependency_graph_behaviour_provider.go b/gapis/api/gles/dependency_graph_behaviour_provider.go index e723dd23af..2a73e062ec 100644 --- a/gapis/api/gles/dependency_graph_behaviour_provider.go +++ b/gapis/api/gles/dependency_graph_behaviour_provider.go @@ -117,7 +117,7 @@ func newGlesDependencyGraphBehaviourProvider() *GlesDependencyGraphBehaviourProv // It is fine to overestimate reads, or to read parent state (i.e. superset). // func (*GlesDependencyGraphBehaviourProvider) GetBehaviourForAtom( - ctx context.Context, s *api.State, id api.CmdID, cmd api.Cmd, g *dependencygraph.DependencyGraph) dependencygraph.AtomBehaviour { + ctx context.Context, s *api.GlobalState, id api.CmdID, cmd api.Cmd, g *dependencygraph.DependencyGraph) dependencygraph.AtomBehaviour { b := dependencygraph.AtomBehaviour{} c := GetContext(s, cmd.Thread()) if c != nil && c.Info.Initialized { @@ -256,7 +256,7 @@ func clearBuffer(g *dependencygraph.DependencyGraph, b *dependencygraph.AtomBeha b.Write(g, data) } -func getAllUsedTextureData(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.State, c *Context) (stateKeys []dependencygraph.StateKey) { +func getAllUsedTextureData(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.GlobalState, c *Context) (stateKeys []dependencygraph.StateKey) { // Look for samplers used by the current program. if prog := c.Bound.Program; prog != nil { for _, activeUniform := range prog.ActiveUniforms { @@ -296,7 +296,7 @@ func getTextureDataAndSize( ctx context.Context, cmd api.Cmd, id api.CmdID, - s *api.State, + s *api.GlobalState, unit *TextureUnit, target GLenum, level GLint) (dependencygraph.StateKey, dependencygraph.StateKey) { diff --git a/gapis/api/gles/draw_call.go b/gapis/api/gles/draw_call.go index a65dba15e8..140b8d53bb 100644 --- a/gapis/api/gles/draw_call.go +++ b/gapis/api/gles/draw_call.go @@ -28,13 +28,13 @@ type drawCall interface { getIndices( ctx context.Context, c *Context, - s *api.State) ([]uint32, uint32, GLenum, error) + s *api.GlobalState) ([]uint32, uint32, GLenum, error) } func (a *GlDrawArrays) getIndices( ctx context.Context, c *Context, - s *api.State) ([]uint32, uint32, GLenum, error) { + s *api.GlobalState) ([]uint32, uint32, GLenum, error) { indices := make([]uint32, a.IndicesCount) for i := range indices { @@ -46,7 +46,7 @@ func (a *GlDrawArrays) getIndices( func (a *GlDrawElements) getIndices( ctx context.Context, c *Context, - s *api.State) ([]uint32, uint32, GLenum, error) { + s *api.GlobalState) ([]uint32, uint32, GLenum, error) { indexSize := map[GLenum]uint64{ GLenum_GL_UNSIGNED_BYTE: 1, @@ -107,102 +107,102 @@ func decodeIndices(r binary.Reader, indicesType GLenum) ([]uint32, error) { } // The draw calls below are stubbed. -func (GlDrawArraysIndirect) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawArraysIndirect) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawArraysIndirect.getIndices() not implemented") } -func (GlDrawArraysInstanced) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawArraysInstanced) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawArraysInstanced.getIndices() not implemented") } -func (GlDrawArraysInstancedANGLE) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawArraysInstancedANGLE) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawArraysInstancedANGLE.getIndices() not implemented") } -func (GlDrawArraysInstancedBaseInstanceEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawArraysInstancedBaseInstanceEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawArraysInstancedBaseInstanceEXT.getIndices() not implemented") } -func (GlDrawArraysInstancedEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawArraysInstancedEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawArraysInstancedEXT.getIndices() not implemented") } -func (GlDrawArraysInstancedNV) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawArraysInstancedNV) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawArraysInstancedNV.getIndices() not implemented") } -func (GlDrawElementsBaseVertex) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsBaseVertex) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsBaseVertex.getIndices() not implemented") } -func (GlDrawElementsBaseVertexEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsBaseVertexEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsBaseVertexEXT.getIndices() not implemented") } -func (GlDrawElementsBaseVertexOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsBaseVertexOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsBaseVertexOES.getIndices() not implemented") } -func (GlDrawElementsIndirect) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsIndirect) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsIndirect.getIndices() not implemented") } -func (GlDrawElementsInstanced) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstanced) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstanced.getIndices() not implemented") } -func (GlDrawElementsInstancedANGLE) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstancedANGLE) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstancedANGLE.getIndices() not implemented") } -func (GlDrawElementsInstancedBaseInstanceEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstancedBaseInstanceEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstancedBaseInstanceEXT.getIndices() not implemented") } -func (GlDrawElementsInstancedBaseVertex) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstancedBaseVertex) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstancedBaseVertex.getIndices() not implemented") } -func (GlDrawElementsInstancedBaseVertexBaseInstanceEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstancedBaseVertexBaseInstanceEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstancedBaseVertexBaseInstanceEXT.getIndices() not implemented") } -func (GlDrawElementsInstancedBaseVertexEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstancedBaseVertexEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstancedBaseVertexEXT.getIndices() not implemented") } -func (GlDrawElementsInstancedBaseVertexOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstancedBaseVertexOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstancedBaseVertexOES.getIndices() not implemented") } -func (GlDrawElementsInstancedEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstancedEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstancedEXT.getIndices() not implemented") } -func (GlDrawElementsInstancedNV) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawElementsInstancedNV) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawElementsInstancedNV.getIndices() not implemented") } -func (GlDrawRangeElements) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawRangeElements) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawRangeElements.getIndices() not implemented") } -func (GlDrawRangeElementsBaseVertex) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawRangeElementsBaseVertex) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawRangeElementsBaseVertex.getIndices() not implemented") } -func (GlDrawRangeElementsBaseVertexEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawRangeElementsBaseVertexEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawRangeElementsBaseVertexEXT.getIndices() not implemented") } -func (GlDrawRangeElementsBaseVertexOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawRangeElementsBaseVertexOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawRangeElementsBaseVertexOES.getIndices() not implemented") } -func (GlDrawTexfOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTexfOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTexfOES.getIndices() not implemented") } -func (GlDrawTexfvOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTexfvOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTexfvOES.getIndices() not implemented") } -func (GlDrawTexiOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTexiOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTexiOES.getIndices() not implemented") } -func (GlDrawTexivOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTexivOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTexivOES.getIndices() not implemented") } -func (GlDrawTexsOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTexsOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTexsOES.getIndices() not implemented") } -func (GlDrawTexsvOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTexsvOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTexsvOES.getIndices() not implemented") } -func (GlDrawTexxOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTexxOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTexxOES.getIndices() not implemented") } -func (GlDrawTexxvOES) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTexxvOES) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTexxvOES.getIndices() not implemented") } -func (GlDrawTransformFeedbackEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTransformFeedbackEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTransformFeedbackEXT.getIndices() not implemented") } -func (GlDrawTransformFeedbackInstancedEXT) getIndices(context.Context, *Context, *api.State) ([]uint32, uint32, GLenum, error) { +func (GlDrawTransformFeedbackInstancedEXT) getIndices(context.Context, *Context, *api.GlobalState) ([]uint32, uint32, GLenum, error) { return nil, 0, 0, fmt.Errorf("GlDrawTransformFeedbackInstancedEXT.getIndices() not implemented") } diff --git a/gapis/api/gles/draw_call_mesh.go b/gapis/api/gles/draw_call_mesh.go index 3e7ee0ebf1..94cda91cd6 100644 --- a/gapis/api/gles/draw_call_mesh.go +++ b/gapis/api/gles/draw_call_mesh.go @@ -39,7 +39,7 @@ func drawCallMesh(ctx context.Context, dc drawCall, p *path.Mesh) (*api.Mesh, er return nil, nil } - s, err := resolve.GlobalState(ctx, cmdPath.StateAfter()) + s, err := resolve.GlobalState(ctx, cmdPath.GlobalStateAfter()) if err != nil { return nil, err } @@ -124,7 +124,7 @@ func drawCallMesh(ctx context.Context, dc drawCall, p *path.Mesh) (*api.Mesh, er DrawPrimitive: drawPrimitive, VertexBuffer: vb, IndexBuffer: ib, - Stats: &api.Mesh_Stats{ + Stats: &api.Mesh_Stats{ Vertices: uint32(len(uniqueIndices)), Indices: origIndexCount, Primitives: drawPrimitive.Count(origIndexCount), @@ -144,7 +144,7 @@ func vertexStreamData( vbb *VertexBufferBinding, vectorCount int, slice U8ˢ, - s *api.State) ([]byte, error) { + s *api.GlobalState) ([]byte, error) { if vbb.Divisor != 0 { return nil, fmt.Errorf("Instanced draw calls not currently supported") diff --git a/gapis/api/gles/externs.go b/gapis/api/gles/externs.go index a7b8676976..3fbb5a2de8 100644 --- a/gapis/api/gles/externs.go +++ b/gapis/api/gles/externs.go @@ -36,7 +36,7 @@ type externs struct { ctx context.Context // Allowed because the externs struct is only a parameter proxy for a single call cmd api.Cmd cmdID api.CmdID - s *api.State + s *api.GlobalState b *rb.Builder } diff --git a/gapis/api/gles/find_issues.go b/gapis/api/gles/find_issues.go index 302194f605..f754b82f67 100644 --- a/gapis/api/gles/find_issues.go +++ b/gapis/api/gles/find_issues.go @@ -42,7 +42,7 @@ import ( // the slice out. Once the last issue is sent (if any) all the chans in out are // closed. type findIssues struct { - state *api.State + state *api.GlobalState device *device.Instance issues []replay.Issue res []replay.Result @@ -126,7 +126,7 @@ func (t *findIssues) Transform(ctx context.Context, id api.CmdID, cmd api.Cmd, o } // Check the result of glGetError after every command. - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { ptr := b.AllocateTemporaryMemory(4) b.Call(funcInfoGlGetError) b.Store(ptr) @@ -205,7 +205,7 @@ func (t *findIssues) Transform(ctx context.Context, id api.CmdID, cmd api.Cmd, o infoLog := make([]byte, buflen) out.MutateAndWrite(ctx, dID, cb.GlGetShaderInfoLog(cmd.Shader, buflen, memory.Nullptr, tmp.Ptr())) - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { b.ReserveMemory(tmp.Range()) b.Post(value.ObservedPointer(tmp.Address()), buflen, func(r binary.Reader, err error) error { if err != nil { @@ -219,7 +219,7 @@ func (t *findIssues) Transform(ctx context.Context, id api.CmdID, cmd api.Cmd, o source := make([]byte, buflen) out.MutateAndWrite(ctx, dID, cb.GlGetShaderSource(cmd.Shader, buflen, memory.Nullptr, tmp.Ptr())) - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { b.ReserveMemory(tmp.Range()) b.Post(value.ObservedPointer(tmp.Address()), buflen, func(r binary.Reader, err error) error { if err != nil { @@ -232,7 +232,7 @@ func (t *findIssues) Transform(ctx context.Context, id api.CmdID, cmd api.Cmd, o })) out.MutateAndWrite(ctx, dID, cb.GlGetShaderiv(cmd.Shader, GLenum_GL_COMPILE_STATUS, tmp.Ptr())) - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { b.ReserveMemory(tmp.Range()) b.Post(value.ObservedPointer(tmp.Address()), 4, func(r binary.Reader, err error) error { if err != nil { @@ -257,7 +257,7 @@ func (t *findIssues) Transform(ctx context.Context, id api.CmdID, cmd api.Cmd, o tmp := t.state.AllocOrPanic(ctx, 4+buflen) out.MutateAndWrite(ctx, dID, cb.GlGetProgramiv(cmd.Program, GLenum_GL_LINK_STATUS, tmp.Ptr())) out.MutateAndWrite(ctx, dID, cb.GlGetProgramInfoLog(cmd.Program, buflen, memory.Nullptr, tmp.Offset(4))) - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { b.ReserveMemory(tmp.Range()) b.Post(value.ObservedPointer(tmp.Address()), 4+buflen, func(r binary.Reader, err error) error { if err != nil { @@ -302,7 +302,7 @@ func (t *findIssues) Transform(ctx context.Context, id api.CmdID, cmd api.Cmd, o func (t *findIssues) Flush(ctx context.Context, out transform.Writer) { cb := CommandBuilder{Thread: 0} - out.MutateAndWrite(ctx, api.CmdNoID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, api.CmdNoID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { // Since the PostBack function is called before the replay target has actually arrived at the post command, // we need to actually write some data here. r.Uint32() is what actually waits for the replay target to have // posted the data in question. If we did not do this, we would shut-down the replay as soon as the second-to-last diff --git a/gapis/api/gles/gles.go b/gapis/api/gles/gles.go index 0f8a6845de..4ad5236423 100644 --- a/gapis/api/gles/gles.go +++ b/gapis/api/gles/gles.go @@ -23,13 +23,14 @@ import ( "github.com/google/gapid/core/log" "github.com/google/gapid/gapis/api" "github.com/google/gapid/gapis/messages" + "github.com/google/gapid/gapis/resolve" "github.com/google/gapid/gapis/resolve/dependencygraph" "github.com/google/gapid/gapis/service/path" ) type CustomState struct{} -func GetContext(s *api.State, thread uint64) *Context { +func GetContext(s *api.GlobalState, thread uint64) *Context { return GetState(s).GetContext(thread) } @@ -37,7 +38,34 @@ func (s *State) GetContext(thread uint64) *Context { return s.Contexts[thread] } -func (c *State) preMutate(ctx context.Context, s *api.State, cmd api.Cmd) error { +// Root returns the path to the root of the state to display. It can vary based +// on filtering mode. Returning nil, nil indicates there is no state to show at +// this point in the capture. +func (s *State) Root(ctx context.Context, p *path.State) (path.Node, error) { + if p.Context == nil || !p.Context.IsValid() { + return p, nil + } + c, err := resolve.Context(ctx, p.After.Capture.Context(p.Context)) + if err != nil { + return nil, err + } + for thread, context := range s.Contexts { + if c.ID() == context.ID() { + return s.contextRoot(p.After, thread), nil + } + } + return nil, nil +} + +func (s *State) contextRoot(p *path.Command, thread uint64) *path.MapIndex { + return path.NewField("Contexts", resolve.APIStateAfter(p, ID)).MapIndex(thread) +} + +func (s *State) objectsRoot(p *path.Command, thread uint64) *path.Field { + return s.contextRoot(p, thread).Field("Objects") +} + +func (c *State) preMutate(ctx context.Context, s *api.GlobalState, cmd api.Cmd) error { c.CurrentContext = c.GetContext(cmd.Thread()) // TODO: Find better way to separate GL and EGL commands. if c.CurrentContext == nil && strings.HasPrefix(cmd.CmdName(), "gl") { @@ -98,7 +126,7 @@ func (b *Texture) GetID() TextureId { } // GetFramebufferAttachmentInfo returns the width, height and format of the specified framebuffer attachment. -func (API) GetFramebufferAttachmentInfo(state *api.State, thread uint64, attachment api.FramebufferAttachment) (width, height uint32, index uint32, format *image.Format, err error) { +func (API) GetFramebufferAttachmentInfo(state *api.GlobalState, thread uint64, attachment api.FramebufferAttachment) (width, height uint32, index uint32, format *image.Format, err error) { s := GetState(state) c := s.GetContext(thread) if c == nil { @@ -123,7 +151,7 @@ func (API) GetFramebufferAttachmentInfo(state *api.State, thread uint64, attachm } // Context returns the active context for the given state and thread. -func (API) Context(s *api.State, thread uint64) api.Context { +func (API) Context(s *api.GlobalState, thread uint64) api.Context { if c := GetContext(s, thread); c != nil { return c } diff --git a/gapis/api/gles/helpers.go b/gapis/api/gles/helpers.go index cb9a9ccfb4..5a26682fa5 100644 --- a/gapis/api/gles/helpers.go +++ b/gapis/api/gles/helpers.go @@ -22,7 +22,7 @@ import ( // BuildProgram returns the atoms to create a shader program with compiled vertex // and fragment shaders. The returned program is not linked. -func BuildProgram(ctx context.Context, s *api.State, cb CommandBuilder, +func BuildProgram(ctx context.Context, s *api.GlobalState, cb CommandBuilder, vertexShaderID, fragmentShaderID ShaderId, programID ProgramId, vertexShaderSource, fragmentShaderSource string) []api.Cmd { return append([]api.Cmd{cb.GlCreateProgram(programID)}, @@ -33,7 +33,7 @@ func BuildProgram(ctx context.Context, s *api.State, cb CommandBuilder, // CompileProgram returns the atoms to compile and then attach vertex and // fragment shaders to an existing shader program. // The returned program is not linked. -func CompileProgram(ctx context.Context, s *api.State, cb CommandBuilder, +func CompileProgram(ctx context.Context, s *api.GlobalState, cb CommandBuilder, vertexShaderID, fragmentShaderID ShaderId, programID ProgramId, vertexShaderSource, fragmentShaderSource string) []api.Cmd { diff --git a/gapis/api/gles/image.go b/gapis/api/gles/image.go index 3dc886e5a9..8fdc2c3b90 100644 --- a/gapis/api/gles/image.go +++ b/gapis/api/gles/image.go @@ -32,13 +32,13 @@ func (i *Image) getUnsizedFormatAndType() (unsizedFormat, ty GLenum) { } func cubemapFaceToLayer(target GLenum) GLint { - layer, _ := subCubemapFaceToLayer(nil, nil, api.CmdNoID, nil, &api.State{}, nil, 0, nil, target) + layer, _ := subCubemapFaceToLayer(nil, nil, api.CmdNoID, nil, &api.GlobalState{}, nil, 0, nil, target) return layer } // getSizedFormatFromTuple returns sized format from unsized format and component type. func getSizedFormatFromTuple(unsizedFormat, ty GLenum) (sizedFormat GLenum) { - sf, _ := subGetSizedFormatFromTuple(nil, nil, api.CmdNoID, nil, &api.State{}, nil, 0, nil, unsizedFormat, ty) + sf, _ := subGetSizedFormatFromTuple(nil, nil, api.CmdNoID, nil, &api.GlobalState{}, nil, 0, nil, unsizedFormat, ty) if sf == GLenum_GL_NONE { panic(fmt.Errorf("Unknown unsized format: %v, %v", unsizedFormat, ty)) } @@ -47,7 +47,7 @@ func getSizedFormatFromTuple(unsizedFormat, ty GLenum) (sizedFormat GLenum) { // getUnsizedFormatAndType returns unsized format and component type from sized format. func getUnsizedFormatAndType(sizedFormat GLenum) (unsizedFormat, ty GLenum) { - info, _ := subGetSizedFormatInfo(nil, nil, api.CmdNoID, nil, &api.State{}, nil, 0, nil, sizedFormat) + info, _ := subGetSizedFormatInfo(nil, nil, api.CmdNoID, nil, &api.GlobalState{}, nil, 0, nil, sizedFormat) if info.SizedFormat == GLenum_GL_NONE { panic(fmt.Errorf("Unknown sized format: %v", sizedFormat)) } @@ -91,7 +91,7 @@ var glChannelToStreamChannel = map[GLenum]stream.Channel{ // getUncompressedStreamFormat returns the decoding format which can be used to read single pixel. func getUncompressedStreamFormat(unsizedFormat, ty GLenum) (format *stream.Format, err error) { - info, _ := subGetUnsizedFormatInfo(nil, nil, api.CmdNoID, nil, &api.State{}, nil, 0, nil, unsizedFormat) + info, _ := subGetUnsizedFormatInfo(nil, nil, api.CmdNoID, nil, &api.GlobalState{}, nil, 0, nil, unsizedFormat) if info.Count == 0 { return nil, fmt.Errorf("Unknown unsized format: %v", unsizedFormat) } diff --git a/gapis/api/gles/links.go b/gapis/api/gles/links.go index 0f0fcf883c..f73b3a2f2a 100644 --- a/gapis/api/gles/links.go +++ b/gapis/api/gles/links.go @@ -31,7 +31,7 @@ func objects(ctx context.Context, p path.Node) (*path.Field, *Context, error) { } thread := cmd.Thread() - stateObj, err := resolve.APIState(ctx, cmdPath.StateAfter()) + stateObj, err := resolve.State(ctx, cmdPath.StateAfter()) if err != nil { return nil, nil, err } @@ -40,10 +40,7 @@ func objects(ctx context.Context, p path.Node) (*path.Field, *Context, error) { if !ok { return nil, nil, nil } - return cmdPath.StateAfter(). - Field("Contexts"). - MapIndex(thread). - Field("Objects"), context, nil + return state.objectsRoot(cmdPath, thread), context, nil } return nil, nil, nil } @@ -58,7 +55,7 @@ func sharedObjects(ctx context.Context, p path.Node) (*path.Field, *Context, err } thread := cmd.Thread() - stateObj, err := resolve.APIState(ctx, cmdPath.StateAfter()) + stateObj, err := resolve.State(ctx, cmdPath.StateAfter()) if err != nil { return nil, nil, err } @@ -67,11 +64,7 @@ func sharedObjects(ctx context.Context, p path.Node) (*path.Field, *Context, err if !ok { return nil, nil, nil } - return cmdPath.StateAfter(). - Field("Contexts"). - MapIndex(thread). - Field("Objects"). - Field("Shared"), context, nil + return state.objectsRoot(cmdPath, thread).Field("Shared"), context, nil } return nil, nil, nil } diff --git a/gapis/api/gles/markers.go b/gapis/api/gles/markers.go index 166951e9c7..d844a21030 100644 --- a/gapis/api/gles/markers.go +++ b/gapis/api/gles/markers.go @@ -23,7 +23,7 @@ import ( ) // Label returns the user maker name. -func (ϟa *GlPushGroupMarkerEXT) Label(ϟctx context.Context, ϟs *api.State) string { +func (ϟa *GlPushGroupMarkerEXT) Label(ϟctx context.Context, ϟs *api.GlobalState) string { ptr := Charᵖ(ϟa.Marker) if ϟa.Length > 0 { return string(memory.CharToBytes(ptr.Slice(0, uint64(ϟa.Length), ϟs.MemoryLayout).Read(ϟctx, ϟa, ϟs, nil))) @@ -32,7 +32,7 @@ func (ϟa *GlPushGroupMarkerEXT) Label(ϟctx context.Context, ϟs *api.State) st } // Label returns the user maker name. -func (ϟa *GlInsertEventMarkerEXT) Label(ϟctx context.Context, ϟs *api.State) string { +func (ϟa *GlInsertEventMarkerEXT) Label(ϟctx context.Context, ϟs *api.GlobalState) string { ptr := Charᵖ(ϟa.Marker) if ϟa.Length > 0 { return string(memory.CharToBytes(ptr.Slice(0, uint64(ϟa.Length), ϟs.MemoryLayout).Read(ϟctx, ϟa, ϟs, nil))) @@ -41,7 +41,7 @@ func (ϟa *GlInsertEventMarkerEXT) Label(ϟctx context.Context, ϟs *api.State) } // Label returns the user maker name. -func (ϟa *GlPushDebugGroup) Label(ϟctx context.Context, ϟs *api.State) string { +func (ϟa *GlPushDebugGroup) Label(ϟctx context.Context, ϟs *api.GlobalState) string { ptr := Charᵖ(ϟa.Message) // This is incorrect, fudging for a bug in Unity which has been fixed but not // rolled out. @@ -55,7 +55,7 @@ func (ϟa *GlPushDebugGroup) Label(ϟctx context.Context, ϟs *api.State) string } // Label returns the user maker name. -func (ϟa *GlPushDebugGroupKHR) Label(ϟctx context.Context, ϟs *api.State) string { +func (ϟa *GlPushDebugGroupKHR) Label(ϟctx context.Context, ϟs *api.GlobalState) string { ptr := Charᵖ(ϟa.Message) // This is incorrect, fudging for a bug in Unity which has been fixed but not // rolled out. diff --git a/gapis/api/gles/read_framebuffer.go b/gapis/api/gles/read_framebuffer.go index 65b8302c70..67d8ea6f90 100644 --- a/gapis/api/gles/read_framebuffer.go +++ b/gapis/api/gles/read_framebuffer.go @@ -37,7 +37,7 @@ func newReadFramebuffer(ctx context.Context) *readFramebuffer { return &readFramebuffer{} } -func getBoundFramebufferID(thread uint64, s *api.State) (FramebufferId, error) { +func getBoundFramebufferID(thread uint64, s *api.GlobalState) (FramebufferId, error) { c := GetContext(s, thread) if c == nil { return 0, fmt.Errorf("No OpenGL ES context") @@ -132,7 +132,7 @@ func (t *readFramebuffer) color( // replay. Note that glReadBuffer was only introduced in // OpenGL ES 3.0, and that GL_FRONT is not a legal enum value. if c.Bound.DrawFramebuffer == c.Objects.Default.Framebuffer { - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { // TODO: We assume here that the default framebuffer is // single-buffered. Once we support double-buffering we // need to decide whether to read from GL_FRONT or GL_BACK. @@ -166,7 +166,7 @@ func (t *readFramebuffer) color( } func postColorData(ctx context.Context, - s *api.State, + s *api.GlobalState, width, height int32, sizedFormat GLenum, out transform.Writer, @@ -188,7 +188,7 @@ func postColorData(ctx context.Context, imageSize := imgFmt.Size(int(width), int(height), 1) tmp := s.AllocOrPanic(ctx, uint64(imageSize)) - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { // TODO: We use Call() directly here because we are calling glReadPixels // with depth formats which are not legal for GLES. Once we're replaying // on-device again, we need to take a look at methods for reading the diff --git a/gapis/api/gles/read_texture.go b/gapis/api/gles/read_texture.go index 9f159747f9..a5da0f3d87 100644 --- a/gapis/api/gles/read_texture.go +++ b/gapis/api/gles/read_texture.go @@ -72,7 +72,7 @@ func (t *readTexture) add(ctx context.Context, r *ReadGPUTextureDataResolveable, } out.MutateAndWrite(ctx, dID, cb.GlGetTexImage(target, GLint(r.Level), GLenum(r.DataFormat), GLenum(r.DataType), tmp.Ptr())) - out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, dID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { b.Post(value.ObservedPointer(tmp.Address()), size, func(r binary.Reader, err error) error { data := make([]byte, size) if err == nil { diff --git a/gapis/api/gles/resources.go b/gapis/api/gles/resources.go index 4c8c2a4c6a..f0ae2f18f2 100644 --- a/gapis/api/gles/resources.go +++ b/gapis/api/gles/resources.go @@ -56,7 +56,7 @@ func (t *Texture) ResourceType(ctx context.Context) api.ResourceType { } // ResourceData returns the resource data given the current state. -func (t *Texture) ResourceData(ctx context.Context, s *api.State) (*api.ResourceData, error) { +func (t *Texture) ResourceData(ctx context.Context, s *api.GlobalState) (*api.ResourceData, error) { ctx = log.Enter(ctx, "Texture.ResourceData()") switch t.Kind { case GLenum_GL_TEXTURE_1D, GLenum_GL_TEXTURE_2D: @@ -188,7 +188,7 @@ func (t *Texture) SetResourceData(ctx context.Context, at *path.Command, } // ImageInfo returns the Image as a image.Info. -func (i *Image) ImageInfo(ctx context.Context, s *api.State) (*image.Info, error) { +func (i *Image) ImageInfo(ctx context.Context, s *api.GlobalState) (*image.Info, error) { out := &image.Info{ Width: uint32(i.Width), Height: uint32(i.Height), @@ -244,7 +244,7 @@ func (s *Shader) ResourceType(ctx context.Context) api.ResourceType { } // ResourceData returns the resource data given the current state. -func (s *Shader) ResourceData(ctx context.Context, t *api.State) (*api.ResourceData, error) { +func (s *Shader) ResourceData(ctx context.Context, t *api.GlobalState) (*api.ResourceData, error) { ctx = log.Enter(ctx, "Shader.ResourceData()") var ty api.ShaderType switch s.ShaderType { @@ -349,7 +349,7 @@ func (p *Program) ResourceType(ctx context.Context) api.ResourceType { } // ResourceData returns the resource data given the current state. -func (p *Program) ResourceData(ctx context.Context, s *api.State) (*api.ResourceData, error) { +func (p *Program) ResourceData(ctx context.Context, s *api.GlobalState) (*api.ResourceData, error) { ctx = log.Enter(ctx, "Program.ResourceData()") shaders := make([]*api.Shader, 0, len(p.Shaders)) @@ -520,7 +520,7 @@ func (p *Program) ResourceData(ctx context.Context, s *api.State) (*api.Resource return api.NewResourceData(&api.Program{Shaders: shaders, Uniforms: uniforms}), nil } -func uniformValue(ctx context.Context, s *api.State, kind api.UniformType, data U8ˢ) interface{} { +func uniformValue(ctx context.Context, s *api.GlobalState, kind api.UniformType, data U8ˢ) interface{} { r := data.Reader(ctx, s) switch kind { diff --git a/gapis/api/gles/stub_program.go b/gapis/api/gles/stub_program.go index e19eed22e1..fce63c1421 100644 --- a/gapis/api/gles/stub_program.go +++ b/gapis/api/gles/stub_program.go @@ -30,7 +30,7 @@ var ( VisibleForTestingStubShaderSource = stubShaderSource ) -func buildStubProgram(ctx context.Context, thread uint64, e *api.CmdExtras, s *api.State, programID ProgramId) []api.Cmd { +func buildStubProgram(ctx context.Context, thread uint64, e *api.CmdExtras, s *api.GlobalState, programID ProgramId) []api.Cmd { programInfo := FindProgramInfo(e) vss, fss, err := stubShaderSource(programInfo) if err != nil { diff --git a/gapis/api/gles/texture_compat.go b/gapis/api/gles/texture_compat.go index 6adff46d15..ff0962fd32 100644 --- a/gapis/api/gles/texture_compat.go +++ b/gapis/api/gles/texture_compat.go @@ -212,7 +212,7 @@ func (tc *textureCompat) postTexParameter(ctx context.Context, target, parameter // decompressTexImage2D writes a glTexImage2D using the decompressed data for // the given glCompressedTexImage2D. -func decompressTexImage2D(ctx context.Context, i api.CmdID, a *GlCompressedTexImage2D, s *api.State, out transform.Writer) error { +func decompressTexImage2D(ctx context.Context, i api.CmdID, a *GlCompressedTexImage2D, s *api.GlobalState, out transform.Writer) error { ctx = log.Enter(ctx, "decompressTexImage2D") dID := i.Derived() c := GetContext(s, a.thread) @@ -265,7 +265,7 @@ func decompressTexImage2D(ctx context.Context, i api.CmdID, a *GlCompressedTexIm // decompressTexSubImage2D writes a glTexSubImage2D using the decompressed data for // the given glCompressedTexSubImage2D. -func decompressTexSubImage2D(ctx context.Context, i api.CmdID, a *GlCompressedTexSubImage2D, s *api.State, out transform.Writer) error { +func decompressTexSubImage2D(ctx context.Context, i api.CmdID, a *GlCompressedTexSubImage2D, s *api.GlobalState, out transform.Writer) error { ctx = log.Enter(ctx, "decompressTexSubImage2D") dID := i.Derived() c := GetContext(s, a.thread) diff --git a/gapis/api/gles/tweaker.go b/gapis/api/gles/tweaker.go index 6942faf0a3..d22eccbfa2 100644 --- a/gapis/api/gles/tweaker.go +++ b/gapis/api/gles/tweaker.go @@ -28,7 +28,7 @@ type tweaker struct { out transform.Writer cb CommandBuilder dID api.CmdID // Derived ID to use for generated atoms. Can be NoID. - s *api.State + s *api.GlobalState c *Context undo []func(context.Context) } diff --git a/gapis/api/gles/undefined_framebuffer.go b/gapis/api/gles/undefined_framebuffer.go index d37fea496a..6c7ca835e3 100644 --- a/gapis/api/gles/undefined_framebuffer.go +++ b/gapis/api/gles/undefined_framebuffer.go @@ -60,7 +60,7 @@ func undefinedFramebuffer(ctx context.Context, device *device.Instance) transfor }) } -func drawUndefinedFramebuffer(ctx context.Context, id api.CmdID, cmd api.Cmd, device *device.Instance, s *api.State, c *Context, out transform.Writer) error { +func drawUndefinedFramebuffer(ctx context.Context, id api.CmdID, cmd api.Cmd, device *device.Instance, s *api.GlobalState, c *Context, out transform.Writer) error { const ( aScreenCoordsLocation AttributeLocation = 0 diff --git a/gapis/api/gles/wireframe.go b/gapis/api/gles/wireframe.go index 095ebc8d06..2ed4f0f62e 100644 --- a/gapis/api/gles/wireframe.go +++ b/gapis/api/gles/wireframe.go @@ -85,7 +85,7 @@ func wireframeOverlay(ctx context.Context, i api.CmdID) transform.Transformer { }) } -func drawWireframe(ctx context.Context, i api.CmdID, dc drawCall, s *api.State, out transform.Writer) error { +func drawWireframe(ctx context.Context, i api.CmdID, dc drawCall, s *api.GlobalState, out transform.Writer) error { c := GetContext(s, dc.Thread()) cb := CommandBuilder{Thread: dc.Thread()} dID := i.Derived() diff --git a/gapis/api/gvr/gvr.go b/gapis/api/gvr/gvr.go index 0ab4d7d387..4bd5d41cf6 100644 --- a/gapis/api/gvr/gvr.go +++ b/gapis/api/gvr/gvr.go @@ -29,7 +29,14 @@ import ( var _ = replay.QueryFramebufferAttachment(API{}) -func (c *State) preMutate(ctx context.Context, s *api.State, cmd api.Cmd) error { +// Root returns the path to the root of the state to display. It can vary based +// on filtering mode. Returning nil, nil indicates there is no state to show at +// this point in the capture. +func (s *State) Root(ctx context.Context, p *path.State) (path.Node, error) { + return nil, nil +} + +func (c *State) preMutate(ctx context.Context, s *api.GlobalState, cmd api.Cmd) error { return nil } @@ -67,12 +74,12 @@ func (API) QueryFramebufferAttachment( } // GetFramebufferAttachmentInfo returns the width, height and format of the specified framebuffer attachment. -func (API) GetFramebufferAttachmentInfo(s *api.State, t uint64, a api.FramebufferAttachment) (width, height, index uint32, format *image.Format, err error) { +func (API) GetFramebufferAttachmentInfo(s *api.GlobalState, t uint64, a api.FramebufferAttachment) (width, height, index uint32, format *image.Format, err error) { return gles.API{}.GetFramebufferAttachmentInfo(s, t, a) } // Context returns the active context for the given state and thread. -func (API) Context(s *api.State, thread uint64) api.Context { +func (API) Context(s *api.GlobalState, thread uint64) api.Context { return gles.API{}.Context(s, thread) } @@ -97,9 +104,9 @@ func (API) ResolveSynchronization(ctx context.Context, d *sync.Data, c *path.Cap // MutateSubcommands mutates the given Cmd and calls callbacks for subcommands // called before and after executing each subcommand callback. -func (API) MutateSubcommands(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.State, - preSubCmdCallback func(*api.State, api.SubCmdIdx, api.Cmd), - postSubCmdCallback func(*api.State, api.SubCmdIdx, api.Cmd)) error { +func (API) MutateSubcommands(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.GlobalState, + preSubCmdCallback func(*api.GlobalState, api.SubCmdIdx, api.Cmd), + postSubCmdCallback func(*api.GlobalState, api.SubCmdIdx, api.Cmd)) error { return nil } diff --git a/gapis/api/labeled.go b/gapis/api/labeled.go index 71ff2d4ed8..adc9c9f41a 100644 --- a/gapis/api/labeled.go +++ b/gapis/api/labeled.go @@ -19,5 +19,5 @@ import "context" // Labeled is the interface implemented commands that have a label. type Labeled interface { // Label returns the commands's label. - Label(ctx context.Context, s *State) string + Label(ctx context.Context, s *GlobalState) string } diff --git a/gapis/api/resource.go b/gapis/api/resource.go index b1d0570889..12ff753ce3 100644 --- a/gapis/api/resource.go +++ b/gapis/api/resource.go @@ -43,7 +43,7 @@ type Resource interface { ResourceType(ctx context.Context) ResourceType // ResourceData returns the resource data given the current state. - ResourceData(ctx context.Context, s *State) (*ResourceData, error) + ResourceData(ctx context.Context, s *GlobalState) (*ResourceData, error) // SetResourceData sets resource data in a new capture. SetResourceData(ctx context.Context, at *path.Command, data *ResourceData, resources ResourceMap, edits ReplaceCallback) error diff --git a/gapis/api/state.go b/gapis/api/state.go index a94bf72080..b558074755 100644 --- a/gapis/api/state.go +++ b/gapis/api/state.go @@ -28,11 +28,12 @@ import ( "github.com/google/gapid/gapis/database" "github.com/google/gapid/gapis/memory" "github.com/google/gapid/gapis/replay/value" + "github.com/google/gapid/gapis/service/path" "github.com/google/gapid/gapis/stringtable" ) -// State represents the graphics state across all contexts. -type State struct { +// GlobalState represents the graphics state across all contexts. +type GlobalState struct { // MemoryLayout holds information about the device memory layout that was // used to create the capture. MemoryLayout *device.MemoryLayout @@ -41,7 +42,7 @@ type State struct { Memory memory.Pools // APIs holds the per-API context states. - APIs map[API]interface{} + APIs map[ID]State // Allocator keeps track of and reserves memory areas not used in the trace. Allocator memory.Allocator @@ -62,9 +63,17 @@ type State struct { AddTag func(msgID uint32, msg *stringtable.Msg) } +// State represents the graphics state for a single context. +type State interface { + // Root returns the path to the root of the state to display. It can vary + // based on filtering mode. Returning nil, nil indicates there is no state + // to show at this point in the capture. + Root(ctx context.Context, p *path.State) (path.Node, error) +} + // NewStateWithEmptyAllocator returns a new, default-initialized State object, // that uses an allocator with no allocations. -func NewStateWithEmptyAllocator(memoryLayout *device.MemoryLayout) *State { +func NewStateWithEmptyAllocator(memoryLayout *device.MemoryLayout) *GlobalState { return NewStateWithAllocator( memory.NewBasicAllocator(value.ValidMemoryRanges), memoryLayout, @@ -73,53 +82,53 @@ func NewStateWithEmptyAllocator(memoryLayout *device.MemoryLayout) *State { // NewStateWithAllocator returns a new, default-initialized State object, // that uses the given memory.Allocator instance. -func NewStateWithAllocator(allocator memory.Allocator, memoryLayout *device.MemoryLayout) *State { - return &State{ +func NewStateWithAllocator(allocator memory.Allocator, memoryLayout *device.MemoryLayout) *GlobalState { + return &GlobalState{ MemoryLayout: memoryLayout, Memory: memory.NewPools(), - APIs: map[API]interface{}{}, + APIs: map[ID]State{}, Allocator: allocator, } } -func (s State) String() string { +func (s GlobalState) String() string { apis := make([]string, 0, len(s.APIs)) for a, s := range s.APIs { apis = append(apis, fmt.Sprintf(" %v: %v", a, s)) } - return fmt.Sprintf("State{\n %v\n Memory:\n%v\n APIs:\n%v\n}", + return fmt.Sprintf("GlobalState{\n %v\n Memory:\n%v\n APIs:\n%v\n}", s.MemoryLayout, s.Memory, strings.Join(apis, "\n")) } // MemoryReader returns a binary reader using the state's memory endianness to // read data from d. -func (s State) MemoryReader(ctx context.Context, d memory.Data) binary.Reader { +func (s GlobalState) MemoryReader(ctx context.Context, d memory.Data) binary.Reader { return endian.Reader(d.NewReader(ctx), s.MemoryLayout.GetEndian()) } // MemoryWriter returns a binary writer using the state's memory endianness to // write data to the pool p, for the range rng. -func (s State) MemoryWriter(p memory.PoolID, rng memory.Range) binary.Writer { +func (s GlobalState) MemoryWriter(p memory.PoolID, rng memory.Range) binary.Writer { bw := memory.Writer(s.Memory.MustGet(p), rng) return endian.Writer(bw, s.MemoryLayout.GetEndian()) } // MemoryDecoder returns a memory decoder using the state's memory layout to // decode data from d. -func (s State) MemoryDecoder(ctx context.Context, d memory.Data) *memory.Decoder { +func (s GlobalState) MemoryDecoder(ctx context.Context, d memory.Data) *memory.Decoder { return memory.NewDecoder(s.MemoryReader(ctx, d), s.MemoryLayout) } // MemoryEncoder returns a memory encoder using the state's memory layout // to encode to the pool p, for the range rng. -func (s State) MemoryEncoder(p memory.PoolID, rng memory.Range) *memory.Encoder { +func (s GlobalState) MemoryEncoder(p memory.PoolID, rng memory.Range) *memory.Encoder { return memory.NewEncoder(s.MemoryWriter(p, rng), s.MemoryLayout) } // Alloc allocates a memory range using the Allocator associated with // the given State, and returns a AllocResult that can be used to access the // pointer, and range. -func (s *State) Alloc(ctx context.Context, size uint64) (AllocResult, error) { +func (s *GlobalState) Alloc(ctx context.Context, size uint64) (AllocResult, error) { at, err := s.Allocator.Alloc(size, 8) if err != nil { return AllocResult{}, err @@ -131,7 +140,7 @@ func (s *State) Alloc(ctx context.Context, size uint64) (AllocResult, error) { // memory range big enough to store it using the Allocator associated with // the given State, and returns a AllocResult that can be used to access the // database ID, pointer, and range. -func (s *State) AllocData(ctx context.Context, v ...interface{}) (AllocResult, error) { +func (s *GlobalState) AllocData(ctx context.Context, v ...interface{}) (AllocResult, error) { buf := &bytes.Buffer{} e := memory.NewEncoder(endian.Writer(buf, s.MemoryLayout.GetEndian()), s.MemoryLayout) memory.Write(e, v) @@ -150,7 +159,7 @@ func (s *State) AllocData(ctx context.Context, v ...interface{}) (AllocResult, e } // AllocOrPanic is like Alloc, but panics if there's an error. -func (s *State) AllocOrPanic(ctx context.Context, size uint64) AllocResult { +func (s *GlobalState) AllocOrPanic(ctx context.Context, size uint64) AllocResult { res, err := s.Alloc(ctx, size) if err != nil { panic(err) @@ -159,7 +168,7 @@ func (s *State) AllocOrPanic(ctx context.Context, size uint64) AllocResult { } // AllocDataOrPanic is like AllocData, but panics if there's an error. -func (s *State) AllocDataOrPanic(ctx context.Context, v ...interface{}) AllocResult { +func (s *GlobalState) AllocDataOrPanic(ctx context.Context, v ...interface{}) AllocResult { res, err := s.AllocData(ctx, v...) if err != nil { panic(err) diff --git a/gapis/api/sync/sync.go b/gapis/api/sync/sync.go index 6b237952b4..8f2da3b483 100644 --- a/gapis/api/sync/sync.go +++ b/gapis/api/sync/sync.go @@ -44,17 +44,17 @@ type SynchronizedAPI interface { // MutateSubcommands mutates the given Cmd and calls callbacks for subcommands // attached to that Cmd. preSubCmdCallback and postSubCmdCallback will be // called before and after executing each subcommand callback. - MutateSubcommands(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.State, - preSubCmdCallback func(*api.State, api.SubCmdIdx, api.Cmd), - postSubCmdCallback func(*api.State, api.SubCmdIdx, api.Cmd)) error + MutateSubcommands(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.GlobalState, + preSubCmdCallback func(*api.GlobalState, api.SubCmdIdx, api.Cmd), + postSubCmdCallback func(*api.GlobalState, api.SubCmdIdx, api.Cmd)) error } type writer struct { - state *api.State + state *api.GlobalState cmds []api.Cmd } -func (s *writer) State() *api.State { return s.state } +func (s *writer) State() *api.GlobalState { return s.state } func (s *writer) MutateAndWrite(ctx context.Context, id api.CmdID, cmd api.Cmd) { cmd.Mutate(ctx, id, s.state, nil) @@ -131,9 +131,9 @@ func MutationCmdsFor(ctx context.Context, c *path.Capture, data *Data, cmds []ap // pre-subcommand callback and the post-subcommand callback will be called // before and after calling each subcommand callback function. func MutateWithSubcommands(ctx context.Context, c *path.Capture, cmds []api.Cmd, - postCmdCb func(*api.State, api.SubCmdIdx, api.Cmd), - preSubCmdCb func(*api.State, api.SubCmdIdx, api.Cmd), - postSubCmdCb func(*api.State, api.SubCmdIdx, api.Cmd)) error { + postCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd), + preSubCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd), + postSubCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd)) error { // This is where we want to handle sub-states // This involves transforming the tree for the given Indices, and // then mutating that. diff --git a/gapis/api/templates/api.go.tmpl b/gapis/api/templates/api.go.tmpl index 7a474aeee0..736d435c42 100644 --- a/gapis/api/templates/api.go.tmpl +++ b/gapis/api/templates/api.go.tmpl @@ -162,7 +162,7 @@ type {{$ty}} [{{$.Size}}]{{Template "Go.Type" $.ValueType}} {{if IsNumericType $.ValueType}} - func (a {{$ty}}) value(ϟb *builder.Builder, ϟa api.Cmd, ϟs *api.State) value.Pointer { + func (a {{$ty}}) value(ϟb *builder.Builder, ϟa api.Cmd, ϟs *api.GlobalState) value.Pointer { for _, v := range a { ϟb.Push({{Template "Go.Replay.Value" "Type" $.ValueType "Name" "v"}}) } @@ -251,19 +251,19 @@ {{if not $el_is_void}} // Read reads and returns the {{$el_ty}} element at the pointer. - func (p {{$ptr_ty}}) Read(ϟctx context.Context, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) {{$el_ty}} { + func (p {{$ptr_ty}}) Read(ϟctx context.Context, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) {{$el_ty}} { return p.Slice(0, 1, ϟs.MemoryLayout).Read(ϟctx, ϟa, ϟs, ϟb)[0] } // Write writes value to the {{$el_ty}} element at the pointer. - func (p {{$ptr_ty}}) Write(ϟctx context.Context, value {{$el_ty}}, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) { + func (p {{$ptr_ty}}) Write(ϟctx context.Context, value {{$el_ty}}, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) { p.Slice(0, 1, ϟs.MemoryLayout).Write(ϟctx, []{{$el_ty}}{value}, ϟa, ϟs, ϟb) } {{end}} {{if $el_is_char}} // StringSlice returns a slice starting at p and ending at the first 0 byte null-terminator. - func (p {{$ptr_ty}}) StringSlice(ϟctx context.Context, ϟs *api.State) Charˢ { + func (p {{$ptr_ty}}) StringSlice(ϟctx context.Context, ϟs *api.GlobalState) Charˢ { i, d := uint64(0), ϟs.MemoryDecoder(ϟctx, ϟs.Memory.MustGet(p.pool).At(p.addr)) for { i++ @@ -301,7 +301,7 @@ } {{if not (GetAnnotation $ "replay_custom_value")}} - func (p {{$ptr_ty}}) value(ϟb *builder.Builder, ϟa api.Cmd, ϟs *api.State) value.Pointer { + func (p {{$ptr_ty}}) value(ϟb *builder.Builder, ϟa api.Cmd, ϟs *api.GlobalState) value.Pointer { if p.addr != 0 { {{if $el_is_ptr}} return value.PointerIndex(p.addr / uint64(ϟs.MemoryLayout.GetPointer().GetSize())) @@ -405,7 +405,7 @@ {{if $el_is_char}} // Make{{$slice_ty}}FromString returns a {{$slice_ty}} backed by a new // memory pool containing a copy of str. - func Make{{$slice_ty}}FromString(str string, ϟs *api.State) {{$slice_ty}} { + func Make{{$slice_ty}}FromString(str string, ϟs *api.GlobalState) {{$slice_ty}} { id, pool := ϟs.Memory.New() pool.Write(0, ϟmem.Blob([]byte(str))) return {{$slice_ty}}{ count: uint64(len(str)), pool: id } @@ -413,13 +413,13 @@ {{end}} // Make{{$slice_ty}} returns a {{$slice_ty}} backed by a new memory pool. - func Make{{$slice_ty}}(count uint64, ϟs *api.State) {{$slice_ty}} { + func Make{{$slice_ty}}(count uint64, ϟs *api.GlobalState) {{$slice_ty}} { id, _ := ϟs.Memory.New() return {{$slice_ty}}{ count: count, pool: id } } // Clone returns a copy of the {{$slice_ty}} in a new memory pool. - func (s {{$slice_ty}}) Clone(ϟctx context.Context, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) {{$slice_ty}} { + func (s {{$slice_ty}}) Clone(ϟctx context.Context, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) {{$slice_ty}} { s.OnRead(ϟctx, ϟa, ϟs, ϟb) id, dst := ϟs.Memory.New() dst.Write(0, ϟs.Memory.MustGet(s.pool).Slice(s.Range(ϟs.MemoryLayout))) @@ -456,7 +456,7 @@ // ResourceID returns an identifier to a resource representing the data of // this slice. - func (s {{$slice_ty}}) ResourceID(ϟctx context.Context, ϟs *api.State) id.ID { + func (s {{$slice_ty}}) ResourceID(ϟctx context.Context, ϟs *api.GlobalState) id.ID { id, err := ϟs.Memory.MustGet(s.pool).Slice(s.Range(ϟs.MemoryLayout)).ResourceID(ϟctx) if err != nil { panic(err) @@ -465,22 +465,22 @@ } // Reader returns a binary reader for the slice. - func (s {{$slice_ty}}) Reader(ϟctx context.Context, ϟs *api.State) binary.Reader { + func (s {{$slice_ty}}) Reader(ϟctx context.Context, ϟs *api.GlobalState) binary.Reader { return ϟs.MemoryReader(ϟctx, ϟs.Memory.MustGet(s.pool).Slice(s.Range(ϟs.MemoryLayout))) } // Writer returns a binary writer for the slice. - func (s {{$slice_ty}}) Writer(ϟs *api.State) binary.Writer { + func (s {{$slice_ty}}) Writer(ϟs *api.GlobalState) binary.Writer { return ϟs.MemoryWriter(s.pool, s.Range(ϟs.MemoryLayout)) } // Decoder returns a memory decoder for the slice. - func (s {{$slice_ty}}) Decoder(ϟctx context.Context, ϟs *api.State) *ϟmem.Decoder { + func (s {{$slice_ty}}) Decoder(ϟctx context.Context, ϟs *api.GlobalState) *ϟmem.Decoder { return ϟs.MemoryDecoder(ϟctx, ϟs.Memory.MustGet(s.pool).Slice(s.Range(ϟs.MemoryLayout))) } // Encoder returns a memory encoder for the slice. - func (s {{$slice_ty}}) Encoder(ϟs *api.State) *ϟmem.Encoder { + func (s {{$slice_ty}}) Encoder(ϟs *api.GlobalState) *ϟmem.Encoder { return ϟs.MemoryEncoder(s.pool, s.Range(ϟs.MemoryLayout)) } @@ -499,7 +499,7 @@ } // Read reads and returns all the {{$el_ty}} elements in this {{$slice_ty}}. - func (s {{$slice_ty}}) Read(ϟctx context.Context, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) []{{$el_ty}} { + func (s {{$slice_ty}}) Read(ϟctx context.Context, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) []{{$el_ty}} { s.OnRead(ϟctx, ϟa, ϟs, ϟb) res := make([]{{$el_ty}}, s.count) d := s.Decoder(ϟctx, ϟs) @@ -510,7 +510,7 @@ // Write copies elements from src to this slice. The number of elements copied is returned // which is the minimum of s.count and len(src). - func (s {{$slice_ty}}) Write(ϟctx context.Context, src []{{$el_ty}}, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) uint64 { + func (s {{$slice_ty}}) Write(ϟctx context.Context, src []{{$el_ty}}, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) uint64 { count := u64.Min(s.count, uint64(len(src))) e := s.Slice(0, count, ϟs.MemoryLayout).Encoder(ϟs) ϟmem.Write(e, src[:count]) @@ -522,7 +522,7 @@ // Copy copies elements from src to this slice. // The number of elements copied is the minimum of dst.Count and src.Count. // The slices of this and dst to the copied elements is returned. - func (dst {{$slice_ty}}) Copy(ϟctx context.Context, src {{$slice_ty}}, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) (d, s {{$slice_ty}}) { + func (dst {{$slice_ty}}) Copy(ϟctx context.Context, src {{$slice_ty}}, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) (d, s {{$slice_ty}}) { count := u64.Min(dst.count, src.count) dst, src = dst.Slice(0, count, ϟs.MemoryLayout), src.Slice(0, count, ϟs.MemoryLayout) {{if $el_is_ptr}} @@ -538,7 +538,7 @@ } // Contains returns true if the slice contains the specified value. - func (s {{$slice_ty}}) Contains(ϟctx context.Context, val {{$el_ty}}, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) bool { + func (s {{$slice_ty}}) Contains(ϟctx context.Context, val {{$el_ty}}, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) bool { for _, e := range s.Read(ϟctx, ϟa, ϟs, ϟb) { if e == val { return true @@ -550,7 +550,7 @@ {{end}} // OnRead calls the backing pool's OnRead callback. s is returned so calls can be chained. - func (s {{$slice_ty}}) OnRead(ϟctx context.Context, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) {{$slice_ty}} { + func (s {{$slice_ty}}) OnRead(ϟctx context.Context, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) {{$slice_ty}} { ϟl := ϟs.MemoryLayout if pool, err := ϟs.Memory.Get(s.pool); err == nil { if f := pool.OnRead; f != nil { @@ -599,7 +599,7 @@ } // OnWrite calls the backing pool's OnWrite callback. s is returned so calls can be chained. - func (s {{$slice_ty}}) OnWrite(ϟctx context.Context, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) {{$slice_ty}} { + func (s {{$slice_ty}}) OnWrite(ϟctx context.Context, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) {{$slice_ty}} { ϟl := ϟs.MemoryLayout if pool, err := ϟs.Memory.Get(s.pool); err == nil { if f := pool.OnWrite; f != nil { @@ -631,7 +631,7 @@ return s } - func (s {{$slice_ty}}) ReserveMemory(ϟctx context.Context, ϟa api.Cmd, ϟs *api.State, ϟb *builder.Builder) {{$slice_ty}} { + func (s {{$slice_ty}}) ReserveMemory(ϟctx context.Context, ϟa api.Cmd, ϟs *api.GlobalState, ϟb *builder.Builder) {{$slice_ty}} { if ϟb != nil && s.pool == ϟmem.ApplicationPool { rng := s.Range(ϟs.MemoryLayout) ϟb.ReserveMemory(ϟmem.Range{Base: s.root, Size: uint64(rng.End() - s.root)}) @@ -874,7 +874,7 @@ } func (ϟa *{{$name}}) API() api.API { return API{} } - func (ϟa *{{$name}}) CmdFlags(ϟctx context.Context, ϟi api.CmdID, ϟs *api.State) api.CmdFlags { + func (ϟa *{{$name}}) CmdFlags(ϟctx context.Context, ϟi api.CmdID, ϟs *api.GlobalState) api.CmdFlags { {{$names := Strings "draw_call" "transform_feedback" "clear" "frame_start" "frame_end" "user_marker" "push_user_marker" "pop_user_marker"}} {{$flags := Strings "DrawCall" "TransformFeedback" "Clear" "StartOfFrame" "EndOfFrame" "UserMarker" "PushUserMarker" "PopUserMarker"}} @@ -954,25 +954,25 @@ {{Template "ClassFields" $}} {{/* TODO: Remove this once closure support is in the API language */}} {{if (eq $.Name "CommandBufferObject")}} - Commands CommandBufferCommands `nobox:"true"` + Commands CommandBufferCommands `hidden:"true" nobox:"true"` {{end}} {{if (eq $.Name "QueueObject")}} - PendingCommands CommandBufferCommands `nobox:"true"` + PendingCommands CommandBufferCommands `hidden:"true" nobox:"true"` {{end}} {{if (eq $.Name "RecreateCmdUpdateBufferData")}} - Data []uint8 `nobox:"true"` + Data []uint8 `hidden:"true" nobox:"true"` {{end}} } {{if GetAnnotation $ "resource"}} // OnCreate should be called immediately after the {{$name}} resource is created. - func (c *{{$name}}) OnCreate(ϟs *api.State) *{{$name}} { + func (c *{{$name}}) OnCreate(ϟs *api.GlobalState) *{{$name}} { if f := ϟs.OnResourceCreated; c.IsResource() && f != nil { f(c) } return c } // OnAccess should be called each time the {{$name}} resource is used. - func (c *{{$name}}) OnAccess(ϟs *api.State) *{{$name}} { + func (c *{{$name}}) OnAccess(ϟs *api.GlobalState) *{{$name}} { if f := ϟs.OnResourceAccessed; c.IsResource() && f != nil { f(c) } return c } @@ -989,12 +989,26 @@ {{AssertType $ "Class"}} {{range $v := $.Fields}} {{$name := $v.Name | GoPublicName}} - {{$cs := ConstantSetIndex $v}} - {{$name}} {{Template "Go.Type" $v}} {{if ge $cs 0}}`constset:"{{$cs}}"`{{end}}{{if GetAnnotation $v "hidden"}}`nobox:"true"`{{end}} + {{$tags := Macro "ClassFieldTags" $v}} + {{$name}} {{Template "Go.Type" $v}} {{if $tags}}`{{$tags}}`{{end}} {{end}} {{end}} +{{/* +------------------------------------------------------------------------------- + Emits a list of tags for the given class field. +------------------------------------------------------------------------------- +*/}} +{{define "ClassFieldTags"}} + {{AssertType $ "Field"}} + {{$cs := ConstantSetIndex $}} + {{if ge $cs 0}}constset:"{{$cs}}" §{{end}} + {{if GetAnnotation $ "hidden"}}hidden:"true" §{{end}} + {{if GetAnnotation $ "nobox"}}nobox:"true" §{{end}} +{{end}} + + {{/* ------------------------------------------------------------------------------- Emits the default value for the specified type. @@ -1103,7 +1117,7 @@ {{range $g := $.Globals}} {{Title $g.Name}} {{Template "Go.Type" $g}} {{end}} - CustomState `nobox:"true"` + CustomState `hidden:"true" nobox:"true"` } func (g *State) Init() { @@ -1124,7 +1138,7 @@ {{define "API"}} {{template "Go.CommentHeader" "API"}} - var apiID = api.ID(id.OfString("{{Global "API"}}")) + var ID = api.ID(id.OfString("{{Global "API"}}")) type API struct {} @@ -1135,7 +1149,7 @@ // ID returns the unique identifier of the {{Global "API"}} API. func (API) ID() api.ID { - return apiID + return ID } // Index returns the Index of the {{Global "API"}} API. @@ -1228,7 +1242,7 @@ Thread uint64 } ¶ - func (cb CommandBuilder) Custom(f func(context.Context, *api.State, *builder.Builder) error) *replay.Custom { + func (cb CommandBuilder) Custom(f func(context.Context, *api.GlobalState, *builder.Builder) error) *replay.Custom { return &replay.Custom{T: cb.Thread, F: f} } ¶ diff --git a/gapis/api/templates/mutate.go.tmpl b/gapis/api/templates/mutate.go.tmpl index 8e2db5dff5..5699bb28c1 100644 --- a/gapis/api/templates/mutate.go.tmpl +++ b/gapis/api/templates/mutate.go.tmpl @@ -41,18 +41,17 @@ ) type callable interface { - Call(context.Context, *api.State, *builder.Builder) + Call(context.Context, *api.GlobalState, *builder.Builder) } // GetState returns the {{$.Name}} state from the api.State. - func GetState(s *api.State) *State { - api := API{} - if state, ok := s.APIs[api].(*State); ok { + func GetState(s *api.GlobalState) *State { + if state, ok := s.APIs[ID].(*State); ok { return state } else { state = &State{} state.Init() - s.APIs[api] = state + s.APIs[ID] = state return state } } @@ -92,7 +91,7 @@ ϟa api.Cmd, § ϟi api.CmdID, § ϟo *api.CmdObservations, § - ϟs *api.State, § + ϟs *api.GlobalState, § ϟc *State, § ϟt uint64, § ϟb *builder.Builder, § @@ -142,7 +141,7 @@ {{end}} func (ϟa *{{$name}}) Mutate(§ {{end}} - ϟctx context.Context, ϟi api.CmdID, ϟs *api.State, ϟb *builder.Builder) error { + ϟctx context.Context, ϟi api.CmdID, ϟs *api.GlobalState, ϟb *builder.Builder) error { {{if not $r}}ϟb = nil // @no_replay{{end}} @@ -168,7 +167,7 @@ // Call builds the replay instructions to push the arguments to the stack and invoke {{$.Name}}(). // Unlike Mutate(), Call() does not perform any state-mutation or memory observations to ϟs.{{if not (IsVoid $.Return.Type)}} // The {{$.Name}}() return value will be stored on the stack.{{end}} - func (ϟa *{{$name}}) Call(ϟctx context.Context, ϟs *api.State, ϟb *builder.Builder) { + func (ϟa *{{$name}}) Call(ϟctx context.Context, ϟs *api.GlobalState, ϟb *builder.Builder) { ϟl := ϟs.MemoryLayout _ = ϟl @@ -244,7 +243,7 @@ {{$u := $ | TypeOf | Underlying}} {{if IsNumericType $u}} {{if not (GetAnnotation $ "replay_custom_value")}} - func (c {{Template "Go.Type" $}}) value(ϟb *builder.Builder, ϟa api.Cmd, ϟs *api.State) value.Value { + func (c {{Template "Go.Type" $}}) value(ϟb *builder.Builder, ϟa api.Cmd, ϟs *api.GlobalState) value.Value { {{if IsSize $.To}} if ϟs.MemoryLayout.GetPointer().GetSize() == 4 { return value.U32(uint32(c)) @@ -270,7 +269,7 @@ {{AssertType $ "Array" "StaticArray"}} {{if not (or (Macro "IsInternal" $.ValueType) (IsAny $.ValueType))}} - func (arr {{Template "Go.Type" $}}) value(ϟb *builder.Builder, ϟa api.Cmd, ϟs *api.State) value.Pointer { + func (arr {{Template "Go.Type" $}}) value(ϟb *builder.Builder, ϟa api.Cmd, ϟs *api.GlobalState) value.Pointer { if len(arr) > 0 { for _, e := range arr { {{Template "PushInput" "Type" $.ValueType "Name" "e"}} diff --git a/gapis/api/test/test.go b/gapis/api/test/test.go index e2b86e7405..cd8ae4e9d4 100644 --- a/gapis/api/test/test.go +++ b/gapis/api/test/test.go @@ -19,20 +19,28 @@ import ( "github.com/google/gapid/core/image" "github.com/google/gapid/gapis/api" + "github.com/google/gapid/gapis/service/path" ) type CustomState struct{} -func (API) GetFramebufferAttachmentInfo(*api.State, uint64, api.FramebufferAttachment) (uint32, uint32, uint32, *image.Format, error) { +func (API) GetFramebufferAttachmentInfo(*api.GlobalState, uint64, api.FramebufferAttachment) (uint32, uint32, uint32, *image.Format, error) { return 0, 0, 0, nil, nil } -func (API) Context(*api.State, uint64) api.Context { return nil } +func (API) Context(*api.GlobalState, uint64) api.Context { return nil } -func (c *State) preMutate(ctx context.Context, s *api.State, cmd api.Cmd) error { +// Root returns the path to the root of the state to display. It can vary based +// on filtering mode. Returning nil, nil indicates there is no state to show at +// this point in the capture. +func (s *State) Root(ctx context.Context, p *path.State) (path.Node, error) { + return nil, nil +} + +func (c *State) preMutate(ctx context.Context, s *api.GlobalState, cmd api.Cmd) error { return nil } -func (i Remapped) remap(cmd api.Cmd, s *api.State) (interface{}, bool) { +func (i Remapped) remap(cmd api.Cmd, s *api.GlobalState) (interface{}, bool) { return i, true } diff --git a/gapis/api/testcmd/cmds.go b/gapis/api/testcmd/cmds.go index 6974a2776e..3be19e8872 100644 --- a/gapis/api/testcmd/cmds.go +++ b/gapis/api/testcmd/cmds.go @@ -36,15 +36,15 @@ type A struct { Flags api.CmdFlags } -func (a *A) Caller() api.CmdID { return api.CmdNoID } -func (a *A) SetCaller(api.CmdID) {} -func (a *A) Thread() uint64 { return 1 } -func (a *A) SetThread(uint64) {} -func (a *A) CmdName() string { return "A" } -func (a *A) API() api.API { return nil } -func (a *A) CmdFlags(context.Context, api.CmdID, *api.State) api.CmdFlags { return a.Flags } -func (a *A) Extras() *api.CmdExtras { return nil } -func (a *A) Mutate(context.Context, api.CmdID, *api.State, *builder.Builder) error { +func (a *A) Caller() api.CmdID { return api.CmdNoID } +func (a *A) SetCaller(api.CmdID) {} +func (a *A) Thread() uint64 { return 1 } +func (a *A) SetThread(uint64) {} +func (a *A) CmdName() string { return "A" } +func (a *A) API() api.API { return nil } +func (a *A) CmdFlags(context.Context, api.CmdID, *api.GlobalState) api.CmdFlags { return a.Flags } +func (a *A) Extras() *api.CmdExtras { return nil } +func (a *A) Mutate(context.Context, api.CmdID, *api.GlobalState, *builder.Builder) error { return nil } @@ -53,15 +53,15 @@ type B struct { Bool bool } -func (*B) Caller() api.CmdID { return api.CmdNoID } -func (*B) SetCaller(api.CmdID) {} -func (*B) Thread() uint64 { return 1 } -func (*B) SetThread(uint64) {} -func (*B) CmdName() string { return "B" } -func (*B) API() api.API { return nil } -func (*B) CmdFlags(context.Context, api.CmdID, *api.State) api.CmdFlags { return 0 } -func (*B) Extras() *api.CmdExtras { return nil } -func (*B) Mutate(context.Context, api.CmdID, *api.State, *builder.Builder) error { +func (*B) Caller() api.CmdID { return api.CmdNoID } +func (*B) SetCaller(api.CmdID) {} +func (*B) Thread() uint64 { return 1 } +func (*B) SetThread(uint64) {} +func (*B) CmdName() string { return "B" } +func (*B) API() api.API { return nil } +func (*B) CmdFlags(context.Context, api.CmdID, *api.GlobalState) api.CmdFlags { return 0 } +func (*B) Extras() *api.CmdExtras { return nil } +func (*B) Mutate(context.Context, api.CmdID, *api.GlobalState, *builder.Builder) error { return nil } @@ -114,15 +114,15 @@ type X struct { PMap IntːStructPtr `param:"PMap"` } -func (X) Caller() api.CmdID { return api.CmdNoID } -func (X) SetCaller(api.CmdID) {} -func (X) Thread() uint64 { return 1 } -func (X) SetThread(uint64) {} -func (X) CmdName() string { return "X" } -func (X) API() api.API { return api.Find(APIID) } -func (X) CmdFlags(context.Context, api.CmdID, *api.State) api.CmdFlags { return 0 } -func (X) Extras() *api.CmdExtras { return nil } -func (X) Mutate(context.Context, api.CmdID, *api.State, *builder.Builder) error { +func (X) Caller() api.CmdID { return api.CmdNoID } +func (X) SetCaller(api.CmdID) {} +func (X) Thread() uint64 { return 1 } +func (X) SetThread(uint64) {} +func (X) CmdName() string { return "X" } +func (X) API() api.API { return api.Find(APIID) } +func (X) CmdFlags(context.Context, api.CmdID, *api.GlobalState) api.CmdFlags { return 0 } +func (X) Extras() *api.CmdExtras { return nil } +func (X) Mutate(context.Context, api.CmdID, *api.GlobalState, *builder.Builder) error { return nil } @@ -132,10 +132,10 @@ func (API) Name() string { return "foo" } func (API) ID() api.ID { return APIID } func (API) Index() uint8 { return 15 } func (API) ConstantSets() *constset.Pack { return nil } -func (API) GetFramebufferAttachmentInfo(*api.State, uint64, api.FramebufferAttachment) (uint32, uint32, uint32, *image.Format, error) { +func (API) GetFramebufferAttachmentInfo(*api.GlobalState, uint64, api.FramebufferAttachment) (uint32, uint32, uint32, *image.Format, error) { return 0, 0, 0, nil, nil } -func (API) Context(*api.State, uint64) api.Context { return nil } +func (API) Context(*api.GlobalState, uint64) api.Context { return nil } func (API) CreateCmd(name string) api.Cmd { switch name { case "X": diff --git a/gapis/api/testcmd/common.go b/gapis/api/testcmd/common.go index bfaa1888b8..fdd5f075df 100644 --- a/gapis/api/testcmd/common.go +++ b/gapis/api/testcmd/common.go @@ -22,12 +22,12 @@ import ( // Writer is a transform.Writer that record all commands that pass through it. type Writer struct { - S *api.State + S *api.GlobalState Cmds []api.Cmd CmdsAndIDs []CmdAndID } -func (w *Writer) State() *api.State { +func (w *Writer) State() *api.GlobalState { return w.S } diff --git a/gapis/api/transform/transformer.go b/gapis/api/transform/transformer.go index f11d9363fc..afebe54bc7 100644 --- a/gapis/api/transform/transformer.go +++ b/gapis/api/transform/transformer.go @@ -43,7 +43,7 @@ type Transformer interface { // There is a configuration flag to switch between the shared/separate modes. type Writer interface { // State returns the state object associated with this writer. - State() *api.State + State() *api.GlobalState // MutateAndWrite mutates the state object associated with this writer, // and it passes the command to further consumers. MutateAndWrite(ctx context.Context, id api.CmdID, cmd api.Cmd) diff --git a/gapis/api/transform/transforms.go b/gapis/api/transform/transforms.go index 51ee30f25b..7951c03ec8 100644 --- a/gapis/api/transform/transforms.go +++ b/gapis/api/transform/transforms.go @@ -82,12 +82,12 @@ func (t transform) Name() string { return t.N } // TransformWriter implements the Writer interface, transforming each command // that is written with T, before writing the result to O. type TransformWriter struct { - S *api.State + S *api.GlobalState T Transformer O Writer } -func (p TransformWriter) State() *api.State { +func (p TransformWriter) State() *api.GlobalState { return p.S } diff --git a/gapis/api/vulkan/buffer_command.go b/gapis/api/vulkan/buffer_command.go index 8578d7597b..8034a5ac89 100644 --- a/gapis/api/vulkan/buffer_command.go +++ b/gapis/api/vulkan/buffer_command.go @@ -24,7 +24,7 @@ import ( ) type CommandBufferCommand struct { - function func(context.Context, api.Cmd, api.CmdID, *api.State, *builder.Builder) + function func(context.Context, api.Cmd, api.CmdID, *api.GlobalState, *builder.Builder) initialCall *api.Cmd submit *api.Cmd submissionIndex []uint64 diff --git a/gapis/api/vulkan/command_buffer_rebuilder.go b/gapis/api/vulkan/command_buffer_rebuilder.go index 4195abfd0d..255eaf87f1 100644 --- a/gapis/api/vulkan/command_buffer_rebuilder.go +++ b/gapis/api/vulkan/command_buffer_rebuilder.go @@ -26,7 +26,7 @@ import ( // unpackMap takes a dense map of u32 -> structure, flattens the map into // a slice, allocates the appropriate data and returns it as well as the // lenth of the map -func unpackMap(ctx context.Context, s *api.State, m interface{}) (api.AllocResult, uint32) { +func unpackMap(ctx context.Context, s *api.GlobalState, m interface{}) (api.AllocResult, uint32) { u32Type := reflect.TypeOf(uint32(0)) t := reflect.TypeOf(m) if t.Kind() != reflect.Map || t.Key() != u32Type { @@ -52,7 +52,7 @@ func allocateNewCmdBufFromExistingOneAndBegin( ctx context.Context, cb CommandBuilder, modelCmdBuf VkCommandBuffer, - s *api.State) (VkCommandBuffer, []api.Cmd, []func()) { + s *api.GlobalState) (VkCommandBuffer, []api.Cmd, []func()) { x := make([]api.Cmd, 0) cleanup := make([]func(), 0) @@ -117,7 +117,7 @@ func rebuildCmdBeginRenderPass( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdBeginRenderPassData) (func(), api.Cmd) { clearValues := make([]VkClearValue, len(d.ClearValues)) @@ -151,7 +151,7 @@ func rebuildCmdEndRenderPass( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdEndRenderPassData) (func(), api.Cmd) { return func() {}, cb.VkCmdEndRenderPass(commandBuffer) } @@ -160,7 +160,7 @@ func rebuildCmdNextSubpass( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdNextSubpassData) (func(), api.Cmd) { return func() {}, cb.VkCmdNextSubpass(commandBuffer, d.Contents) } @@ -169,7 +169,7 @@ func rebuildCmdBindPipeline( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdBindPipelineData) (func(), api.Cmd) { return func() {}, cb.VkCmdBindPipeline(commandBuffer, @@ -180,7 +180,7 @@ func rebuildCmdBindIndexBuffer( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdBindIndexBufferData) (func(), api.Cmd) { return func() {}, cb.VkCmdBindIndexBuffer(commandBuffer, @@ -191,7 +191,7 @@ func rebuildCmdSetLineWidth( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetLineWidthData) (func(), api.Cmd) { return func() {}, cb.VkCmdSetLineWidth(commandBuffer, d.LineWidth) @@ -201,7 +201,7 @@ func rebuildCmdBindDescriptorSets( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdBindDescriptorSetsData) (func(), api.Cmd) { descriptorSetData, descriptorSetCount := unpackMap(ctx, s, d.DescriptorSets) @@ -227,7 +227,7 @@ func rebuildCmdBindVertexBuffers( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdBindVertexBuffersData) (func(), api.Cmd) { bufferData, _ := unpackMap(ctx, s, d.Buffers) @@ -248,7 +248,7 @@ func rebuildCmdWaitEvents( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdWaitEventsData) (func(), api.Cmd) { eventData, eventCount := unpackMap(ctx, s, d.Events) @@ -279,7 +279,7 @@ func rebuildCmdPipelineBarrier( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdPipelineBarrierData) (func(), api.Cmd) { memoryBarrierData, memoryBarrierCount := unpackMap(ctx, s, d.MemoryBarriers) @@ -307,7 +307,7 @@ func rebuildCmdBeginQuery( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdBeginQueryData) (func(), api.Cmd) { return func() {}, cb.VkCmdBeginQuery(commandBuffer, d.QueryPool, d.Query, d.Flags) @@ -317,7 +317,7 @@ func rebuildCmdBlitImage( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdBlitImageData) (func(), api.Cmd) { blitData, blitCount := unpackMap(ctx, s, d.Regions) @@ -339,7 +339,7 @@ func rebuildCmdClearAttachments( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdClearAttachmentsData) (func(), api.Cmd) { clearAttachmentData, clearCount := unpackMap(ctx, s, d.Attachments) @@ -360,7 +360,7 @@ func rebuildCmdClearColorImage( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdClearColorImageData) (func(), api.Cmd) { colorData := s.AllocDataOrPanic(ctx, d.Color) @@ -383,7 +383,7 @@ func rebuildCmdClearDepthStencilImage( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdClearDepthStencilImageData) (func(), api.Cmd) { depthStencilData := s.AllocDataOrPanic(ctx, d.DepthStencil) @@ -406,7 +406,7 @@ func rebuildCmdCopyBuffer( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdCopyBufferData) (func(), api.Cmd) { regionData, regionCount := unpackMap(ctx, s, d.CopyRegions) @@ -425,7 +425,7 @@ func rebuildCmdCopyBufferToImage( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCopyBufferToImageData) (func(), api.Cmd) { regionData, regionCount := unpackMap(ctx, s, d.Regions) @@ -445,7 +445,7 @@ func rebuildCmdCopyImage( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdCopyImageData) (func(), api.Cmd) { regionData, regionCount := unpackMap(ctx, s, d.Regions) @@ -466,7 +466,7 @@ func rebuildCmdCopyImageToBuffer( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCopyImageToBufferData) (func(), api.Cmd) { regionData, regionCount := unpackMap(ctx, s, d.Regions) @@ -486,7 +486,7 @@ func rebuildCmdCopyQueryPoolResults( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdCopyQueryPoolResultsData) (func(), api.Cmd) { return func() {}, cb.VkCmdCopyQueryPoolResults(commandBuffer, @@ -504,7 +504,7 @@ func rebuildCmdDispatch( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDispatchData) (func(), api.Cmd) { return func() {}, cb.VkCmdDispatch(commandBuffer, @@ -518,7 +518,7 @@ func rebuildCmdDispatchIndirect( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDispatchIndirectData) (func(), api.Cmd) { return func() {}, cb.VkCmdDispatchIndirect(commandBuffer, @@ -531,7 +531,7 @@ func rebuildCmdDraw( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDrawData) (func(), api.Cmd) { return func() {}, cb.VkCmdDraw(commandBuffer, @@ -546,7 +546,7 @@ func rebuildCmdDrawIndexed( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDrawIndexedData) (func(), api.Cmd) { return func() {}, cb.VkCmdDrawIndexed(commandBuffer, d.IndexCount, @@ -557,7 +557,7 @@ func rebuildCmdDrawIndexedIndirect( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDrawIndexedIndirectData) (func(), api.Cmd) { return func() {}, cb.VkCmdDrawIndexedIndirect(commandBuffer, @@ -572,7 +572,7 @@ func rebuildCmdDrawIndirect( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDrawIndirectData) (func(), api.Cmd) { return func() {}, cb.VkCmdDrawIndirect(commandBuffer, @@ -587,7 +587,7 @@ func rebuildCmdEndQuery( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdEndQueryData) (func(), api.Cmd) { return func() {}, cb.VkCmdEndQuery(commandBuffer, @@ -600,7 +600,7 @@ func rebuildCmdExecuteCommands( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdExecuteCommandsData) (func(), api.Cmd) { commandBufferData, commandBufferCount := unpackMap(ctx, s, d.CommandBuffers) @@ -617,7 +617,7 @@ func rebuildCmdFillBuffer( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdFillBufferData) (func(), api.Cmd) { return func() { @@ -633,7 +633,7 @@ func rebuildCmdPushConstants( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdPushConstantsDataExpanded) (func(), api.Cmd) { data := s.AllocDataOrPanic(ctx, d.Data) @@ -653,7 +653,7 @@ func rebuildCmdResetQueryPool( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdResetQueryPoolData) (func(), api.Cmd) { return func() { @@ -668,7 +668,7 @@ func rebuildCmdResolveImage( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdResolveImageData) (func(), api.Cmd) { resolveData, resolveCount := unpackMap(ctx, s, d.ResolveRegions) @@ -689,7 +689,7 @@ func rebuildCmdSetBlendConstants( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetBlendConstantsData) (func(), api.Cmd) { var constants F32ː4ᵃ @@ -708,7 +708,7 @@ func rebuildCmdSetDepthBias( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetDepthBiasData) (func(), api.Cmd) { return func() { @@ -723,7 +723,7 @@ func rebuildCmdSetDepthBounds( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetDepthBoundsData) (func(), api.Cmd) { return func() { @@ -737,7 +737,7 @@ func rebuildCmdSetEvent( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetEventData) (func(), api.Cmd) { return func() { @@ -751,7 +751,7 @@ func rebuildCmdResetEvent( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdResetEventData) (func(), api.Cmd) { return func() { }, cb.VkCmdResetEvent(commandBuffer, @@ -764,7 +764,7 @@ func rebuildCmdSetScissor( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetScissorData) (func(), api.Cmd) { scissorData, scissorCount := unpackMap(ctx, s, d.Scissors) @@ -782,7 +782,7 @@ func rebuildCmdSetStencilCompareMask( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetStencilCompareMaskData) (func(), api.Cmd) { return func() { @@ -796,7 +796,7 @@ func rebuildCmdSetStencilReference( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetStencilReferenceData) (func(), api.Cmd) { return func() { @@ -810,7 +810,7 @@ func rebuildCmdSetStencilWriteMask( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetStencilWriteMaskData) (func(), api.Cmd) { return func() { @@ -824,7 +824,7 @@ func rebuildCmdSetViewport( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdSetViewportData) (func(), api.Cmd) { viewportData, viewportCount := unpackMap(ctx, s, d.Viewports) @@ -842,7 +842,7 @@ func rebuildCmdUpdateBuffer( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdUpdateBufferData) (func(), api.Cmd) { data := s.AllocDataOrPanic(ctx, d.Data) @@ -861,7 +861,7 @@ func rebuildCmdWriteTimestamp( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdWriteTimestampData) (func(), api.Cmd) { return func() { @@ -876,7 +876,7 @@ func rebuildCmdDebugMarkerBeginEXT( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDebugMarkerBeginEXTData) (func(), api.Cmd) { markerNameData := s.AllocDataOrPanic(ctx, d.MarkerName) var color F32ː4ᵃ @@ -902,7 +902,7 @@ func rebuildCmdDebugMarkerEndEXT( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDebugMarkerEndEXTData) (func(), api.Cmd) { return func() {}, cb.VkCmdDebugMarkerEndEXT(commandBuffer) } @@ -911,7 +911,7 @@ func rebuildCmdDebugMarkerInsertEXT( ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, d *RecreateCmdDebugMarkerInsertEXTData) (func(), api.Cmd) { markerNameData := s.AllocDataOrPanic(ctx, d.MarkerName) var color F32ː4ᵃ @@ -940,7 +940,7 @@ func rebuildCmdDebugMarkerInsertEXT( func AddCommand(ctx context.Context, cb CommandBuilder, commandBuffer VkCommandBuffer, - s *api.State, + s *api.GlobalState, rebuildInfo interface{}) (func(), api.Cmd) { switch t := rebuildInfo.(type) { case *RecreateCmdBeginRenderPassData: diff --git a/gapis/api/vulkan/custom_replay.go b/gapis/api/vulkan/custom_replay.go index 1bcd39aebc..2c8d4be23b 100644 --- a/gapis/api/vulkan/custom_replay.go +++ b/gapis/api/vulkan/custom_replay.go @@ -23,217 +23,217 @@ import ( "github.com/google/gapid/gapis/replay/builder" ) -func (i VkInstance) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkInstance) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkPhysicalDevice) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkPhysicalDevice) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkDevice) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkDevice) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkQueue) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkQueue) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkCommandBuffer) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkCommandBuffer) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkSemaphore) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkSemaphore) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkFence) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkFence) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkDeviceMemory) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkDeviceMemory) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkBuffer) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkBuffer) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkImage) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkImage) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkEvent) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkEvent) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkQueryPool) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkQueryPool) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkBufferView) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkBufferView) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkImageView) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkImageView) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkShaderModule) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkShaderModule) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkPipelineCache) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkPipelineCache) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkPipelineLayout) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkPipelineLayout) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkRenderPass) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkRenderPass) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkPipeline) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkPipeline) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkDescriptorSetLayout) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkDescriptorSetLayout) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkSampler) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkSampler) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkDescriptorPool) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkDescriptorPool) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkDescriptorSet) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkDescriptorSet) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkFramebuffer) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkFramebuffer) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkCommandPool) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkCommandPool) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkSurfaceKHR) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkSurfaceKHR) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkSwapchainKHR) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkSwapchainKHR) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkDisplayKHR) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkDisplayKHR) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkDisplayModeKHR) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkDisplayModeKHR) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (i VkDebugReportCallbackEXT) remap(api.Cmd, *api.State) (key interface{}, remap bool) { +func (i VkDebugReportCallbackEXT) remap(api.Cmd, *api.GlobalState) (key interface{}, remap bool) { if i != 0 { key, remap = i, true } return } -func (a *VkCreateInstance) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkCreateInstance) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { cb := CommandBuilder{Thread: a.thread} // Hijack VkCreateInstance's Mutate() method entirely with our ReplayCreateVkInstance's Mutate(). @@ -256,7 +256,7 @@ func (a *VkCreateInstance) Mutate(ctx context.Context, id api.CmdID, s *api.Stat return cb.ReplayRegisterVkInstance(instance).Mutate(ctx, id, s, b) } -func (a *VkDestroyInstance) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkDestroyInstance) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { cb := CommandBuilder{Thread: a.thread} // Call the underlying vkDestroyInstance() and do the observation. err := a.mutate(ctx, id, s, b) @@ -267,12 +267,12 @@ func (a *VkDestroyInstance) Mutate(ctx context.Context, id api.CmdID, s *api.Sta return cb.ReplayUnregisterVkInstance(a.Instance).Mutate(ctx, id, s, b) } -func EnterRecreate(ctx context.Context, s *api.State) func() { +func EnterRecreate(ctx context.Context, s *api.GlobalState) func() { GetState(s).IsRebuilding = true return func() { GetState(s).IsRebuilding = false } } -func (a *RecreateInstance) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateInstance) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -281,11 +281,11 @@ func (a *RecreateInstance) Mutate(ctx context.Context, id api.CmdID, s *api.Stat return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateState) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateState) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { return nil } -func (a *RecreatePhysicalDevices) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreatePhysicalDevices) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkEnumeratePhysicalDevices(a.Instance, a.Count, a.PPhysicalDevices, VkResult(0)) @@ -293,7 +293,7 @@ func (a *RecreatePhysicalDevices) Mutate(ctx context.Context, id api.CmdID, s *a return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateDevice) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDevice) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -301,14 +301,14 @@ func (a *RecreateDevice) Mutate(ctx context.Context, id api.CmdID, s *api.State, hijack.Extras().MustClone(a.Extras().All()...) return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateQueue) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateQueue) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkGetDeviceQueue(a.Device, a.QueueFamilyIndex, a.QueueIndex, a.PQueue) hijack.Extras().MustClone(a.Extras().All()...) return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateDeviceMemory) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDeviceMemory) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -328,7 +328,7 @@ func (a *RecreateDeviceMemory) Mutate(ctx context.Context, id api.CmdID, s *api. return err } -func (a *RecreateAndBeginCommandBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateAndBeginCommandBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkAllocateCommandBuffers(a.Device, a.PAllocateInfo, a.PCommandBuffer, VkResult(0)) @@ -347,7 +347,7 @@ func (a *RecreateAndBeginCommandBuffer) Mutate(ctx context.Context, id api.CmdID return err } -func (a *RecreateEndCommandBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateEndCommandBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkEndCommandBuffer(a.CommandBuffer, VkResult(0)) @@ -357,7 +357,7 @@ func (a *RecreateEndCommandBuffer) Mutate(ctx context.Context, id api.CmdID, s * ////////////// Command Buffer Commands -func (a *RecreateCmdUpdateBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdUpdateBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdUpdateBuffer(a.CommandBuffer, a.DstBuffer, a.DstOffset, a.DataSize, a.PData) @@ -365,7 +365,7 @@ func (a *RecreateCmdUpdateBuffer) Mutate(ctx context.Context, id api.CmdID, s *a return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdPipelineBarrier) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdPipelineBarrier) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdPipelineBarrier(a.CommandBuffer, @@ -382,7 +382,7 @@ func (a *RecreateCmdPipelineBarrier) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdCopyBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdCopyBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdCopyBuffer(a.CommandBuffer, a.SrcBuffer, a.DstBuffer, a.RegionCount, a.PRegions) @@ -390,7 +390,7 @@ func (a *RecreateCmdCopyBuffer) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdResolveImage) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdResolveImage) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdResolveImage(a.CommandBuffer, a.SrcImage, a.SrcImageLayout, a.DstImage, a.DstImageLayout, a.RegionCount, a.PRegions) @@ -398,7 +398,7 @@ func (a *RecreateCmdResolveImage) Mutate(ctx context.Context, id api.CmdID, s *a return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdBeginRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdBeginRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdBeginRenderPass(a.CommandBuffer, a.PRenderPassBegin, a.Contents) @@ -406,7 +406,7 @@ func (a *RecreateCmdBeginRenderPass) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdBindPipeline) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdBindPipeline) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdBindPipeline(a.CommandBuffer, a.PipelineBindPoint, a.Pipeline) @@ -414,7 +414,7 @@ func (a *RecreateCmdBindPipeline) Mutate(ctx context.Context, id api.CmdID, s *a return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdBindDescriptorSets) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdBindDescriptorSets) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdBindDescriptorSets( @@ -430,7 +430,7 @@ func (a *RecreateCmdBindDescriptorSets) Mutate(ctx context.Context, id api.CmdID return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdBindVertexBuffers) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdBindVertexBuffers) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdBindVertexBuffers( @@ -443,7 +443,7 @@ func (a *RecreateCmdBindVertexBuffers) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdBindIndexBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdBindIndexBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdBindIndexBuffer( @@ -455,7 +455,7 @@ func (a *RecreateCmdBindIndexBuffer) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdEndRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdEndRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdEndRenderPass( @@ -464,7 +464,7 @@ func (a *RecreateCmdEndRenderPass) Mutate(ctx context.Context, id api.CmdID, s * return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdExecuteCommands) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdExecuteCommands) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdExecuteCommands( @@ -476,7 +476,7 @@ func (a *RecreateCmdExecuteCommands) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdNextSubpass) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdNextSubpass) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdNextSubpass( @@ -487,7 +487,7 @@ func (a *RecreateCmdNextSubpass) Mutate(ctx context.Context, id api.CmdID, s *ap return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDrawIndexed) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDrawIndexed) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDrawIndexed( @@ -501,7 +501,7 @@ func (a *RecreateCmdDrawIndexed) Mutate(ctx context.Context, id api.CmdID, s *ap return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDispatch) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDispatch) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDispatch( @@ -513,7 +513,7 @@ func (a *RecreateCmdDispatch) Mutate(ctx context.Context, id api.CmdID, s *api.S return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDispatchIndirect) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDispatchIndirect) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDispatchIndirect( @@ -524,7 +524,7 @@ func (a *RecreateCmdDispatchIndirect) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDrawIndirect) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDrawIndirect) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDrawIndirect( @@ -537,7 +537,7 @@ func (a *RecreateCmdDrawIndirect) Mutate(ctx context.Context, id api.CmdID, s *a return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDrawIndexedIndirect) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDrawIndexedIndirect) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDrawIndexedIndirect( @@ -550,7 +550,7 @@ func (a *RecreateCmdDrawIndexedIndirect) Mutate(ctx context.Context, id api.CmdI return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetDepthBias) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetDepthBias) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetDepthBias( @@ -562,7 +562,7 @@ func (a *RecreateCmdSetDepthBias) Mutate(ctx context.Context, id api.CmdID, s *a return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetDepthBounds) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetDepthBounds) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetDepthBounds( @@ -573,7 +573,7 @@ func (a *RecreateCmdSetDepthBounds) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetBlendConstants) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetBlendConstants) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetBlendConstants( @@ -583,7 +583,7 @@ func (a *RecreateCmdSetBlendConstants) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetStencilCompareMask) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetStencilCompareMask) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetStencilCompareMask( @@ -595,7 +595,7 @@ func (a *RecreateCmdSetStencilCompareMask) Mutate(ctx context.Context, id api.Cm return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetStencilWriteMask) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetStencilWriteMask) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetStencilWriteMask( @@ -607,7 +607,7 @@ func (a *RecreateCmdSetStencilWriteMask) Mutate(ctx context.Context, id api.CmdI return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetStencilReference) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetStencilReference) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetStencilReference( @@ -619,7 +619,7 @@ func (a *RecreateCmdSetStencilReference) Mutate(ctx context.Context, id api.CmdI return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdFillBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdFillBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdFillBuffer( @@ -632,7 +632,7 @@ func (a *RecreateCmdFillBuffer) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetLineWidth) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetLineWidth) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetLineWidth( @@ -642,7 +642,7 @@ func (a *RecreateCmdSetLineWidth) Mutate(ctx context.Context, id api.CmdID, s *a return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdCopyBufferToImage) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdCopyBufferToImage) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdCopyBufferToImage( @@ -656,7 +656,7 @@ func (a *RecreateCmdCopyBufferToImage) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdCopyImageToBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdCopyImageToBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdCopyImageToBuffer( @@ -670,7 +670,7 @@ func (a *RecreateCmdCopyImageToBuffer) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdBlitImage) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdBlitImage) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdBlitImage( @@ -687,7 +687,7 @@ func (a *RecreateCmdBlitImage) Mutate(ctx context.Context, id api.CmdID, s *api. return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdCopyImage) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdCopyImage) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdCopyImage( @@ -702,7 +702,7 @@ func (a *RecreateCmdCopyImage) Mutate(ctx context.Context, id api.CmdID, s *api. return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdPushConstants) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdPushConstants) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdPushConstants( @@ -716,7 +716,7 @@ func (a *RecreateCmdPushConstants) Mutate(ctx context.Context, id api.CmdID, s * return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDraw) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDraw) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDraw( @@ -729,7 +729,7 @@ func (a *RecreateCmdDraw) Mutate(ctx context.Context, id api.CmdID, s *api.State return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetScissor) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetScissor) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetScissor( @@ -741,7 +741,7 @@ func (a *RecreateCmdSetScissor) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetViewport) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetViewport) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetViewport( @@ -753,7 +753,7 @@ func (a *RecreateCmdSetViewport) Mutate(ctx context.Context, id api.CmdID, s *ap return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdBeginQuery) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdBeginQuery) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdBeginQuery( @@ -765,7 +765,7 @@ func (a *RecreateCmdBeginQuery) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdEndQuery) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdEndQuery) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdEndQuery( @@ -776,7 +776,7 @@ func (a *RecreateCmdEndQuery) Mutate(ctx context.Context, id api.CmdID, s *api.S return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdClearAttachments) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdClearAttachments) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdClearAttachments( @@ -790,7 +790,7 @@ func (a *RecreateCmdClearAttachments) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdClearColorImage) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdClearColorImage) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdClearColorImage( @@ -805,7 +805,7 @@ func (a *RecreateCmdClearColorImage) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdClearDepthStencilImage) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdClearDepthStencilImage) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdClearDepthStencilImage( @@ -820,7 +820,7 @@ func (a *RecreateCmdClearDepthStencilImage) Mutate(ctx context.Context, id api.C return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdResetQueryPool) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdResetQueryPool) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdResetQueryPool( @@ -832,7 +832,7 @@ func (a *RecreateCmdResetQueryPool) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdCopyQueryPoolResults) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdCopyQueryPoolResults) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdCopyQueryPoolResults( @@ -849,7 +849,7 @@ func (a *RecreateCmdCopyQueryPoolResults) Mutate(ctx context.Context, id api.Cmd return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdWriteTimestamp) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdWriteTimestamp) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdWriteTimestamp( @@ -862,7 +862,7 @@ func (a *RecreateCmdWriteTimestamp) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdSetEvent) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdSetEvent) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdSetEvent( @@ -874,7 +874,7 @@ func (a *RecreateCmdSetEvent) Mutate(ctx context.Context, id api.CmdID, s *api.S return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdResetEvent) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdResetEvent) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdResetEvent( @@ -886,7 +886,7 @@ func (a *RecreateCmdResetEvent) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdWaitEvents) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdWaitEvents) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdWaitEvents( @@ -906,7 +906,7 @@ func (a *RecreateCmdWaitEvents) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDebugMarkerBeginEXT) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDebugMarkerBeginEXT) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDebugMarkerBeginEXT(a.CommandBuffer, a.PMarkerInfo) @@ -914,7 +914,7 @@ func (a *RecreateCmdDebugMarkerBeginEXT) Mutate(ctx context.Context, id api.CmdI return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDebugMarkerEndEXT) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDebugMarkerEndEXT) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDebugMarkerEndEXT(a.CommandBuffer) @@ -922,7 +922,7 @@ func (a *RecreateCmdDebugMarkerEndEXT) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateCmdDebugMarkerInsertEXT) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCmdDebugMarkerInsertEXT) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCmdDebugMarkerInsertEXT(a.CommandBuffer, a.PMarkerInfo) @@ -930,7 +930,7 @@ func (a *RecreateCmdDebugMarkerInsertEXT) Mutate(ctx context.Context, id api.Cmd return hijack.Mutate(ctx, id, s, b) } -func (a *RecreatePhysicalDeviceProperties) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreatePhysicalDeviceProperties) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkGetPhysicalDeviceQueueFamilyProperties( @@ -949,7 +949,7 @@ func (a *RecreatePhysicalDeviceProperties) Mutate(ctx context.Context, id api.Cm return memoryProperties.Mutate(ctx, id, s, b) } -func (a *RecreateSemaphore) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateSemaphore) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -996,7 +996,7 @@ func (a *RecreateSemaphore) Mutate(ctx context.Context, id api.CmdID, s *api.Sta } -func (a *RecreateFence) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateFence) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1005,7 +1005,7 @@ func (a *RecreateFence) Mutate(ctx context.Context, id api.CmdID, s *api.State, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateEvent) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateEvent) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1028,7 +1028,7 @@ func (a *RecreateEvent) Mutate(ctx context.Context, id api.CmdID, s *api.State, return nil } -func (a *RecreateCommandPool) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateCommandPool) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1037,7 +1037,7 @@ func (a *RecreateCommandPool) Mutate(ctx context.Context, id api.CmdID, s *api.S return hijack.Mutate(ctx, id, s, b) } -func (a *RecreatePipelineCache) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreatePipelineCache) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1046,7 +1046,7 @@ func (a *RecreatePipelineCache) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateDescriptorSetLayout) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDescriptorSetLayout) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1055,7 +1055,7 @@ func (a *RecreateDescriptorSetLayout) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreatePipelineLayout) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreatePipelineLayout) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1064,7 +1064,7 @@ func (a *RecreatePipelineLayout) Mutate(ctx context.Context, id api.CmdID, s *ap return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1073,7 +1073,7 @@ func (a *RecreateRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.St return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateShaderModule) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateShaderModule) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1082,7 +1082,7 @@ func (a *RecreateShaderModule) Mutate(ctx context.Context, id api.CmdID, s *api. return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateDestroyShaderModule) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDestroyShaderModule) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1091,7 +1091,7 @@ func (a *RecreateDestroyShaderModule) Mutate(ctx context.Context, id api.CmdID, return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateDestroyRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDestroyRenderPass) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1100,7 +1100,7 @@ func (a *RecreateDestroyRenderPass) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateDescriptorPool) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDescriptorPool) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1109,7 +1109,7 @@ func (a *RecreateDescriptorPool) Mutate(ctx context.Context, id api.CmdID, s *ap return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateXCBSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateXCBSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1118,7 +1118,7 @@ func (a *RecreateXCBSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateXlibSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateXlibSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1127,7 +1127,7 @@ func (a *RecreateXlibSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *ap return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateWaylandSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateWaylandSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1136,7 +1136,7 @@ func (a *RecreateWaylandSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateMirSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateMirSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1145,7 +1145,7 @@ func (a *RecreateMirSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateAndroidSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateAndroidSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1154,7 +1154,7 @@ func (a *RecreateAndroidSurfaceKHR) Mutate(ctx context.Context, id api.CmdID, s return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateImageView) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateImageView) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1163,7 +1163,7 @@ func (a *RecreateImageView) Mutate(ctx context.Context, id api.CmdID, s *api.Sta return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateSampler) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateSampler) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCreateSampler( @@ -1176,7 +1176,7 @@ func (a *RecreateSampler) Mutate(ctx context.Context, id api.CmdID, s *api.State return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateFramebuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateFramebuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1185,7 +1185,7 @@ func (a *RecreateFramebuffer) Mutate(ctx context.Context, id api.CmdID, s *api.S return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateDescriptorSet) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDescriptorSet) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkAllocateDescriptorSets(a.Device, a.PAllocateInfo, a.PDescriptorSet, VkResult(0)) @@ -1198,7 +1198,7 @@ func (a *RecreateDescriptorSet) Mutate(ctx context.Context, id api.CmdID, s *api return write.Mutate(ctx, id, s, b) } -func (a *RecreateGraphicsPipeline) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateGraphicsPipeline) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCreateGraphicsPipelines(a.Device, a.PipelineCache, uint32(1), a.PCreateInfo, memory.Nullptr, a.PPipeline, VkResult(0)) @@ -1206,7 +1206,7 @@ func (a *RecreateGraphicsPipeline) Mutate(ctx context.Context, id api.CmdID, s * return hijack.Mutate(ctx, id, s, b) } -func (a *RecreateComputePipeline) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateComputePipeline) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} hijack := cb.VkCreateComputePipelines(a.Device, a.PipelineCache, uint32(1), a.PCreateInfo, memory.Nullptr, a.PPipeline, VkResult(0)) @@ -1214,7 +1214,7 @@ func (a *RecreateComputePipeline) Mutate(ctx context.Context, id api.CmdID, s *a return hijack.Mutate(ctx, id, s, b) } -func (a *VkCreateDevice) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkCreateDevice) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { // Hijack VkCreateDevice's Mutate() method entirely with our // ReplayCreateVkDevice's Mutate(). Similar to VkCreateInstance's Mutate() // above. @@ -1271,7 +1271,7 @@ func (a *VkCreateDevice) Mutate(ctx context.Context, id api.CmdID, s *api.State, return cb.ReplayRegisterVkDevice(a.PhysicalDevice, device, a.PCreateInfo).Mutate(ctx, id, s, b) } -func (a *VkDestroyDevice) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkDestroyDevice) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { // Call the underlying vkDestroyDevice() and do the observation. cb := CommandBuilder{Thread: a.thread} err := a.mutate(ctx, id, s, b) @@ -1282,7 +1282,7 @@ func (a *VkDestroyDevice) Mutate(ctx context.Context, id api.CmdID, s *api.State return cb.ReplayUnregisterVkDevice(a.Device).Mutate(ctx, id, s, b) } -func (a *VkAllocateCommandBuffers) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkAllocateCommandBuffers) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { // Call the underlying vkAllocateCommandBuffers() and do the observation. cb := CommandBuilder{Thread: a.thread} err := a.mutate(ctx, id, s, b) @@ -1294,7 +1294,7 @@ func (a *VkAllocateCommandBuffers) Mutate(ctx context.Context, id api.CmdID, s * return cb.ReplayRegisterVkCommandBuffers(a.Device, count, a.PCommandBuffers).Mutate(ctx, id, s, b) } -func (a *VkFreeCommandBuffers) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkFreeCommandBuffers) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { // Call the underlying vkFreeCommandBuffers() and do the observation. cb := CommandBuilder{Thread: a.thread} err := a.mutate(ctx, id, s, b) @@ -1306,7 +1306,7 @@ func (a *VkFreeCommandBuffers) Mutate(ctx context.Context, id api.CmdID, s *api. return cb.ReplayUnregisterVkCommandBuffers(count, a.PCommandBuffers).Mutate(ctx, id, s, b) } -func (a *VkCreateSwapchainKHR) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkCreateSwapchainKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { // Call the underlying VkCreateSwapchainKHR() and do the observation cb := CommandBuilder{Thread: a.thread} err := a.mutate(ctx, id, s, b) @@ -1316,7 +1316,7 @@ func (a *VkCreateSwapchainKHR) Mutate(ctx context.Context, id api.CmdID, s *api. return cb.ToggleVirtualSwapchainReturnAcquiredImage(a.PSwapchain).Mutate(ctx, id, s, b) } -func (a *VkAcquireNextImageKHR) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkAcquireNextImageKHR) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { l := s.MemoryLayout o := a.Extras().Observations() o.ApplyReads(s.Memory.ApplicationPool()) @@ -1332,7 +1332,7 @@ func (a *VkAcquireNextImageKHR) Mutate(ctx context.Context, id api.CmdID, s *api return nil } -func (a *VkGetFenceStatus) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkGetFenceStatus) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { cb := CommandBuilder{Thread: a.thread} err := a.mutate(ctx, id, s, b) if b == nil || err != nil { @@ -1342,7 +1342,7 @@ func (a *VkGetFenceStatus) Mutate(ctx context.Context, id api.CmdID, s *api.Stat return cb.ReplayGetFenceStatus(a.Device, a.Fence, a.Result, a.Result).Mutate(ctx, id, s, b) } -func (a *VkGetEventStatus) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *VkGetEventStatus) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { cb := CommandBuilder{Thread: a.thread} err := a.mutate(ctx, id, s, b) if b == nil || err != nil { @@ -1361,7 +1361,7 @@ func (a *VkGetEventStatus) Mutate(ctx context.Context, id api.CmdID, s *api.Stat return cb.ReplayGetEventStatus(a.Device, a.Event, a.Result, wait, a.Result).Mutate(ctx, id, s, b) } -func (a *RecreateDebugMarkerSetObjectNameEXT) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDebugMarkerSetObjectNameEXT) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { o := a.Extras().Observations() o.ApplyReads(s.Memory.ApplicationPool()) nameInfo := a.PNameInfo.Read(ctx, a, s, nil) @@ -1372,7 +1372,7 @@ func (a *RecreateDebugMarkerSetObjectNameEXT) Mutate(ctx context.Context, id api return a.mutate(ctx, id, s, b) } -func (a *RecreateDebugMarkerSetObjectTagEXT) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateDebugMarkerSetObjectTagEXT) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { o := a.Extras().Observations() o.ApplyReads(s.Memory.ApplicationPool()) tagInfo := a.PTagInfo.Read(ctx, a, s, nil) @@ -1383,7 +1383,7 @@ func (a *RecreateDebugMarkerSetObjectTagEXT) Mutate(ctx context.Context, id api. return a.mutate(ctx, id, s, b) } -func (a *ReplayAllocateImageMemory) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *ReplayAllocateImageMemory) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { if err := a.mutate(ctx, id, s, b); err != nil { return err } @@ -1410,7 +1410,7 @@ func (a *ReplayAllocateImageMemory) Mutate(ctx context.Context, id api.CmdID, s return err } -func createEndCommandBufferAndQueueSubmit(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, queue VkQueue, commandBuffer VkCommandBuffer) error { +func createEndCommandBufferAndQueueSubmit(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, queue VkQueue, commandBuffer VkCommandBuffer) error { commandBuffers := s.AllocDataOrPanic(ctx, commandBuffer) defer commandBuffers.Free() submitInfo := VkSubmitInfo{ @@ -1447,7 +1447,7 @@ func createEndCommandBufferAndQueueSubmit(ctx context.Context, id api.CmdID, cb ).Mutate(ctx, id, s, b) } -func createImageTransition(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, +func createImageTransition(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, srcLayout VkImageLayout, dstLayout VkImageLayout, image VkImage, aspectMask VkImageAspectFlags, commandBuffer VkCommandBuffer) error { @@ -1493,7 +1493,7 @@ func createImageTransition(ctx context.Context, id api.CmdID, cb CommandBuilder, return transfer.Mutate(ctx, id, s, b) } -func createAndBeginCommandBuffer(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, device VkDevice, commandPool VkCommandPool) (VkCommandBuffer, error) { +func createAndBeginCommandBuffer(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, device VkDevice, commandPool VkCommandPool) (VkCommandBuffer, error) { commandBufferAllocateInfo := VkCommandBufferAllocateInfo{ SType: VkStructureType_VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, PNext: NewVoidᶜᵖ(memory.Nullptr), @@ -1539,7 +1539,7 @@ func createAndBeginCommandBuffer(ctx context.Context, id api.CmdID, cb CommandBu ).Mutate(ctx, id, s, b) } -func createAndBindSourceBuffer(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, device VkDevice, size VkDeviceSize, memoryIndex uint32) (VkBuffer, VkDeviceMemory, error) { +func createAndBindSourceBuffer(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, device VkDevice, size VkDeviceSize, memoryIndex uint32) (VkBuffer, VkDeviceMemory, error) { bufferCreateInfo := VkBufferCreateInfo{ SType: VkStructureType_VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, PNext: NewVoidᶜᵖ(memory.Nullptr), @@ -1606,7 +1606,7 @@ func createAndBindSourceBuffer(ctx context.Context, id api.CmdID, cb CommandBuil return bufferId, memoryId, nil } -func (a *RecreateBufferView) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateBufferView) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1615,7 +1615,7 @@ func (a *RecreateBufferView) Mutate(ctx context.Context, id api.CmdID, s *api.St return hijack.Mutate(ctx, id, s, b) } -func mapBufferMemory(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, cmd api.Cmd, device VkDevice, size VkDeviceSize, mem VkDeviceMemory) (Voidᵖ, uint64, error) { +func mapBufferMemory(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, cmd api.Cmd, device VkDevice, size VkDeviceSize, mem VkDeviceMemory) (Voidᵖ, uint64, error) { at, err := s.Allocator.Alloc(uint64(size), 8) if err != nil { return NewVoidᵖ(memory.Nullptr), at, err @@ -1632,7 +1632,7 @@ func mapBufferMemory(ctx context.Context, id api.CmdID, cb CommandBuilder, s *ap return NewVoidᵖᵖ(mappedPointer.Ptr()).Read(ctx, cmd, s, b), at, err } -func flushBufferMemory(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, device VkDevice, size VkDeviceSize, mem VkDeviceMemory, mapped U8ᵖ) error { +func flushBufferMemory(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, device VkDevice, size VkDeviceSize, mem VkDeviceMemory, mapped U8ᵖ) error { flushRange := VkMappedMemoryRange{ SType: VkStructureType_VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, PNext: NewVoidᶜᵖ(memory.Nullptr), @@ -1650,7 +1650,7 @@ func flushBufferMemory(ctx context.Context, id api.CmdID, cb CommandBuilder, s * AddRead(slice.Range(s.MemoryLayout), slice.ResourceID(ctx, s)).Mutate(ctx, id, s, b) } -func createBufferBarrier(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, buffer VkBuffer, size VkDeviceSize, commandBuffer VkCommandBuffer) error { +func createBufferBarrier(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, buffer VkBuffer, size VkDeviceSize, commandBuffer VkCommandBuffer) error { allBits := uint32(VkAccessFlagBits_VK_ACCESS_MEMORY_WRITE_BIT<<1) - 1 bufferBarrier := VkBufferMemoryBarrier{ @@ -1685,7 +1685,7 @@ func createBufferBarrier(ctx context.Context, id api.CmdID, cb CommandBuilder, s return transfer.Mutate(ctx, id, s, b) } -func createCommandPool(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, queue VkQueue, device VkDevice) (VkCommandPool, error) { +func createCommandPool(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, queue VkQueue, device VkDevice) (VkCommandPool, error) { // Command pool and command buffer commandPoolId := VkCommandPool(newUnusedID(false, func(x uint64) bool { _, ok := GetState(s).CommandPools[VkCommandPool(x)]; return ok })) queueObject := GetState(s).Queues[queue] @@ -1713,11 +1713,11 @@ func createCommandPool(ctx context.Context, id api.CmdID, cb CommandBuilder, s * ).Mutate(ctx, id, s, b) } -func destroyCommandPool(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.State, b *builder.Builder, device VkDevice, commandPool VkCommandPool) error { +func destroyCommandPool(ctx context.Context, id api.CmdID, cb CommandBuilder, s *api.GlobalState, b *builder.Builder, device VkDevice, commandPool VkCommandPool) error { return cb.VkDestroyCommandPool(device, commandPool, memory.Nullptr).Mutate(ctx, id, s, b) } -func (a *RecreateImage) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateImage) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() cb := CommandBuilder{Thread: a.thread} allocator := memory.Nullptr @@ -1729,7 +1729,7 @@ func (a *RecreateImage) Mutate(ctx context.Context, id api.CmdID, s *api.State, return nil } -func (a *RecreateBindImageMemory) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateBindImageMemory) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() if a.Memory != VkDeviceMemory(0) { cb := CommandBuilder{Thread: a.thread} @@ -1740,7 +1740,7 @@ func (a *RecreateBindImageMemory) Mutate(ctx context.Context, id api.CmdID, s *a return nil } -func (a *RecreateImageData) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateImageData) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() l := s.MemoryLayout t := a.thread @@ -1877,7 +1877,7 @@ func (a *RecreateImageData) Mutate(ctx context.Context, id api.CmdID, s *api.Sta return nil } -func (a *RecreateBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() // ApplyReads() is necessary only because we need to access the Read // observation data prior to calling the VkCreateBuffer's Mutate(). @@ -1899,7 +1899,7 @@ func (a *RecreateBuffer) Mutate(ctx context.Context, id api.CmdID, s *api.State, return nil } -func (a *RecreateBindBufferMemory) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateBindBufferMemory) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() if a.Memory != VkDeviceMemory(0) { cb := CommandBuilder{Thread: a.thread} @@ -1910,7 +1910,7 @@ func (a *RecreateBindBufferMemory) Mutate(ctx context.Context, id api.CmdID, s * return nil } -func (a *RecreateBufferData) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateBufferData) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() l := s.MemoryLayout o := a.Extras().Observations() @@ -1994,7 +1994,7 @@ func (a *RecreateBufferData) Mutate(ctx context.Context, id api.CmdID, s *api.St // Returns a queue capable of graphics and compute operations if it could be // found, a compute only queue or copy queue will be returned if it could not // be found -func findGraphicsAndComputeQueueForDevice(device VkDevice, s *api.State) VkQueue { +func findGraphicsAndComputeQueueForDevice(device VkDevice, s *api.GlobalState) VkQueue { c := GetState(s) backupQueue := VkQueue(0) backupQueueFlags := uint32(0) @@ -2017,7 +2017,7 @@ func findGraphicsAndComputeQueueForDevice(device VkDevice, s *api.State) VkQueue return backupQueue } -func (a *RecreateQueryPool) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateQueryPool) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() l := s.MemoryLayout allocator := memory.Nullptr @@ -2085,7 +2085,7 @@ func (a *RecreateQueryPool) Mutate(ctx context.Context, id api.CmdID, s *api.Sta } -func (a *RecreateSwapchain) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (a *RecreateSwapchain) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { defer EnterRecreate(ctx, s)() l := s.MemoryLayout allocator := memory.Nullptr diff --git a/gapis/api/vulkan/draw_call_mesh.go b/gapis/api/vulkan/draw_call_mesh.go index 64f3401d2d..f2c75ede4c 100644 --- a/gapis/api/vulkan/draw_call_mesh.go +++ b/gapis/api/vulkan/draw_call_mesh.go @@ -35,7 +35,7 @@ func drawCallMesh(ctx context.Context, dc *VkQueueSubmit, p *path.Mesh) (*api.Me return nil, nil } - s, err := resolve.GlobalState(ctx, cmdPath.StateAfter()) + s, err := resolve.GlobalState(ctx, cmdPath.GlobalStateAfter()) if err != nil { return nil, err } @@ -160,7 +160,7 @@ func drawCallMesh(ctx context.Context, dc *VkQueueSubmit, p *path.Mesh) (*api.Me return mesh, nil } -func getIndicesData(ctx context.Context, s *api.State, boundIndexBuffer *BoundIndexBuffer, indexCount, firstIndex uint32, vertexOffset int32) []uint32 { +func getIndicesData(ctx context.Context, s *api.GlobalState, boundIndexBuffer *BoundIndexBuffer, indexCount, firstIndex uint32, vertexOffset int32) []uint32 { backingMem := boundIndexBuffer.BoundBuffer.Buffer.Memory if backingMem == nil { return []uint32{} @@ -206,7 +206,7 @@ func getIndicesData(ctx context.Context, s *api.State, boundIndexBuffer *BoundIn return []uint32{} } -func getVertexBuffers(ctx context.Context, s *api.State, thread uint64, +func getVertexBuffers(ctx context.Context, s *api.GlobalState, thread uint64, vertexCount, firstVertex uint32) (*vertex.Buffer, error) { if vertexCount == 0 { @@ -268,7 +268,7 @@ func getVertexBuffers(ctx context.Context, s *api.State, thread uint64, return vb, nil } -func getVerticesData(ctx context.Context, s *api.State, thread uint64, +func getVerticesData(ctx context.Context, s *api.GlobalState, thread uint64, boundVertexBuffer BoundBuffer, vertexCount, firstVertex uint32, binding VkVertexInputBindingDescription, attribute VkVertexInputAttributeDescription) ([]byte, error) { diff --git a/gapis/api/vulkan/externs.go b/gapis/api/vulkan/externs.go index c178f0debf..8f577be4f9 100644 --- a/gapis/api/vulkan/externs.go +++ b/gapis/api/vulkan/externs.go @@ -30,7 +30,7 @@ type externs struct { ctx context.Context // Allowed because the externs struct is only a parameter proxy for a single call cmd api.Cmd cmdID api.CmdID - s *api.State + s *api.GlobalState b *rb.Builder } @@ -63,7 +63,7 @@ func (e externs) mapMemory(value Voidᵖᵖ, slice memory.Slice) { } } -func (e externs) callSub(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.State, b *rb.Builder, sub, data interface{}) { +func (e externs) callSub(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.GlobalState, b *rb.Builder, sub, data interface{}) { reflect.ValueOf(sub).Call([]reflect.Value{ reflect.ValueOf(ctx), reflect.ValueOf(cmd), @@ -81,7 +81,7 @@ func (e externs) addCmd(commandBuffer VkCommandBuffer, recreate_data interface{} o := GetState(e.s).CommandBuffers.Get(commandBuffer) o.Commands = append(o.Commands, CommandBufferCommand{ - func(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.State, b *rb.Builder) { + func(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.GlobalState, b *rb.Builder) { e.callSub(ctx, cmd, id, s, b, functionToCall, data) }, &e.cmd, nil, []uint64(nil), recreate_data, true, }) @@ -211,7 +211,7 @@ func (e externs) execPendingCommands(queue VkQueue) { func (e externs) recordUpdateSemaphoreSignal(semaphore VkSemaphore, Signaled bool) { signal_semaphore := CommandBufferCommand{ - function: func(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.State, b *rb.Builder) { + function: func(ctx context.Context, cmd api.Cmd, id api.CmdID, s *api.GlobalState, b *rb.Builder) { if s, ok := GetState(s).Semaphores[semaphore]; ok { s.Signaled = Signaled } diff --git a/gapis/api/vulkan/find_issues.go b/gapis/api/vulkan/find_issues.go index 2c972608c3..79f8702f4f 100644 --- a/gapis/api/vulkan/find_issues.go +++ b/gapis/api/vulkan/find_issues.go @@ -44,7 +44,7 @@ func (t *findIssues) Transform(ctx context.Context, id api.CmdID, cmd api.Cmd, o func (t *findIssues) Flush(ctx context.Context, out transform.Writer) { cb := CommandBuilder{Thread: 0} - out.MutateAndWrite(ctx, api.CmdNoID, cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + out.MutateAndWrite(ctx, api.CmdNoID, cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { // Since the PostBack function is called before the replay target has actually arrived at the post command, // we need to actually write some data here. r.Uint32() is what actually waits for the replay target to have // posted the data in question. If we did not do this, we would shut-down the replay as soon as the second-to-last diff --git a/gapis/api/vulkan/footprint_builder.go b/gapis/api/vulkan/footprint_builder.go index 8136106c03..0017bcfa8e 100644 --- a/gapis/api/vulkan/footprint_builder.go +++ b/gapis/api/vulkan/footprint_builder.go @@ -823,7 +823,7 @@ func (ds *descriptorSet) useDescriptors(ctx context.Context, } func (ds *descriptorSet) writeDescriptors(ctx context.Context, - cmd api.Cmd, s *api.State, vb *FootprintBuilder, + cmd api.Cmd, s *api.GlobalState, vb *FootprintBuilder, bh *dependencygraph.Behavior, write VkWriteDescriptorSet) { l := s.MemoryLayout @@ -893,7 +893,7 @@ func (ds *descriptorSet) writeDescriptors(ctx context.Context, } func (ds *descriptorSet) copyDescriptors(ctx context.Context, - cmd api.Cmd, s *api.State, bh *dependencygraph.Behavior, + cmd api.Cmd, s *api.GlobalState, bh *dependencygraph.Behavior, srcDs *descriptorSet, copy VkCopyDescriptorSet) { dstElm := uint64(copy.DstArrayElement) srcElm := uint64(copy.SrcArrayElement) @@ -1201,7 +1201,7 @@ func (vb *FootprintBuilder) readBoundIndexBuffer(ctx context.Context, } func (vb *FootprintBuilder) recordBarriers(ctx context.Context, - s *api.State, ft *dependencygraph.Footprint, cmd api.Cmd, + s *api.GlobalState, ft *dependencygraph.Footprint, cmd api.Cmd, bh *dependencygraph.Behavior, vkCb VkCommandBuffer, memoryBarrierCount uint32, bufferBarrierCount uint32, pBufferBarriers VkBufferMemoryBarrierᶜᵖ, imageBarrierCount uint32, pImageBarriers VkImageMemoryBarrierᶜᵖ, @@ -1245,7 +1245,7 @@ func (vb *FootprintBuilder) recordBarriers(ctx context.Context, // BuildFootprint incrementally builds the given Footprint with the given // command specified with api.CmdID and api.Cmd. func (vb *FootprintBuilder) BuildFootprint(ctx context.Context, - s *api.State, ft *dependencygraph.Footprint, id api.CmdID, cmd api.Cmd) { + s *api.GlobalState, ft *dependencygraph.Footprint, id api.CmdID, cmd api.Cmd) { l := s.MemoryLayout diff --git a/gapis/api/vulkan/read_framebuffer.go b/gapis/api/vulkan/read_framebuffer.go index 5d0e4525df..0ef8c35d95 100644 --- a/gapis/api/vulkan/read_framebuffer.go +++ b/gapis/api/vulkan/read_framebuffer.go @@ -162,7 +162,7 @@ func newUnusedID(isDispatchable bool, existenceTest func(uint64) bool) uint64 { func postImageData(ctx context.Context, cb CommandBuilder, - s *api.State, + s *api.GlobalState, imageObject *ImageObject, vkFormat VkFormat, aspectMask VkImageAspectFlagBits, @@ -226,7 +226,7 @@ func postImageData(ctx context.Context, d.Free() } }() - MustAllocData := func(ctx context.Context, s *api.State, v ...interface{}) api.AllocResult { + MustAllocData := func(ctx context.Context, s *api.GlobalState, v ...interface{}) api.AllocResult { allocate_result := s.AllocDataOrPanic(ctx, v...) allocated = append(allocated, &allocate_result) return allocate_result @@ -988,7 +988,7 @@ func postImageData(ctx context.Context, // Add post command writeEach(ctx, out, - cb.Custom(func(ctx context.Context, s *api.State, b *builder.Builder) error { + cb.Custom(func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error { b.Post(value.ObservedPointer(at), uint64(bufferSize), func(r binary.Reader, err error) error { var bytes []byte if err == nil { diff --git a/gapis/api/vulkan/resources.go b/gapis/api/vulkan/resources.go index 441003cbba..ba9b42ba5c 100644 --- a/gapis/api/vulkan/resources.go +++ b/gapis/api/vulkan/resources.go @@ -495,7 +495,7 @@ func setCubemapFace(img *image.Info, cubeMap *api.CubemapLevel, layerIndex uint3 } // ResourceData returns the resource data given the current state. -func (t *ImageObject) ResourceData(ctx context.Context, s *api.State) (*api.ResourceData, error) { +func (t *ImageObject) ResourceData(ctx context.Context, s *api.GlobalState) (*api.ResourceData, error) { ctx = log.Enter(ctx, "ImageObject.ResourceData()") vkFmt := t.Info.Format format, err := getImageFormatFromVulkanFormat(vkFmt) @@ -576,7 +576,7 @@ func (s *ShaderModuleObject) ResourceType(ctx context.Context) api.ResourceType } // ResourceData returns the resource data given the current state. -func (s *ShaderModuleObject) ResourceData(ctx context.Context, t *api.State) (*api.ResourceData, error) { +func (s *ShaderModuleObject) ResourceData(ctx context.Context, t *api.GlobalState) (*api.ResourceData, error) { ctx = log.Enter(ctx, "ShaderModuleObject.ResourceData()") words := s.Words.Read(ctx, nil, t, nil) source := shadertools.DisassembleSpirvBinary(words) diff --git a/gapis/api/vulkan/vulkan.api b/gapis/api/vulkan/vulkan.api index b10796da63..6f7c8b40da 100644 --- a/gapis/api/vulkan/vulkan.api +++ b/gapis/api/vulkan/vulkan.api @@ -9406,8 +9406,8 @@ enum RecordingState { VkDeviceSize MappedSize void* MappedLocation u32 MemoryTypeIndex - @hidden @internal u8[] Data - @unused ref!VulkanDebugMarkerInfo DebugInfo + @hidden @nobox @internal u8[] Data + @unused ref!VulkanDebugMarkerInfo DebugInfo ref!DedicatedAllocationMemoryAllocateInfoNV DedicatedAllocationNV } @@ -9475,11 +9475,11 @@ enum RecordingState { } @internal class ImageLevel { - u32 Width - u32 Height - @unused u32 Depth - @hidden @internal u8[] Data - @unused u32 Size + u32 Width + u32 Height + @unused u32 Depth + @hidden @nobox @internal u8[] Data + @unused u32 Size } @internal class ImageViewObject { diff --git a/gapis/api/vulkan/vulkan.go b/gapis/api/vulkan/vulkan.go index 9b80a03d86..b7a4580f3c 100644 --- a/gapis/api/vulkan/vulkan.go +++ b/gapis/api/vulkan/vulkan.go @@ -40,7 +40,7 @@ type CustomState struct { popMarkerGroup func(ty MarkerType) } -func getStateObject(s *api.State) *State { +func getStateObject(s *api.GlobalState) *State { return GetState(s) } @@ -62,15 +62,22 @@ func (VulkanContext) API() api.API { return API{} } -func (API) Context(s *api.State, thread uint64) api.Context { +func (API) Context(s *api.GlobalState, thread uint64) api.Context { return VulkanContext{} } -func (c *State) preMutate(ctx context.Context, s *api.State, cmd api.Cmd) error { +// Root returns the path to the root of the state to display. It can vary based +// on filtering mode. Returning nil, nil indicates there is no state to show at +// this point in the capture. +func (*State) Root(ctx context.Context, p *path.State) (path.Node, error) { + return p, nil +} + +func (c *State) preMutate(ctx context.Context, s *api.GlobalState, cmd api.Cmd) error { return nil } -func (API) GetFramebufferAttachmentInfo(state *api.State, thread uint64, attachment api.FramebufferAttachment) (w, h uint32, a uint32, f *image.Format, err error) { +func (API) GetFramebufferAttachmentInfo(state *api.GlobalState, thread uint64, attachment api.FramebufferAttachment) (w, h uint32, a uint32, f *image.Format, err error) { w, h, form, i, err := GetState(state).getFramebufferAttachmentInfo(attachment) switch attachment { case api.FramebufferAttachment_Stencil: @@ -353,8 +360,8 @@ func (API) GetTerminator(ctx context.Context, c *path.Capture) (transform.Termin } func (API) MutateSubcommands(ctx context.Context, id api.CmdID, cmd api.Cmd, - s *api.State, preSubCmdCb func(*api.State, api.SubCmdIdx, api.Cmd), - postSubCmdCb func(*api.State, api.SubCmdIdx, api.Cmd)) error { + s *api.GlobalState, preSubCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd), + postSubCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd)) error { c := GetState(s) if postSubCmdCb != nil { c.PostSubcommand = func(interface{}) { diff --git a/gapis/api/vulkan/vulkan_terminator.go b/gapis/api/vulkan/vulkan_terminator.go index 3822da746d..048eda6525 100644 --- a/gapis/api/vulkan/vulkan_terminator.go +++ b/gapis/api/vulkan/vulkan_terminator.go @@ -127,7 +127,7 @@ func incrementLoopLevel(idx api.SubCmdIdx, loopLevel *int) bool { // resolveCurrentRenderPass walks all of the current and pending commands // to determine what renderpass we are in after the idx'th subcommand -func resolveCurrentRenderPass(ctx context.Context, s *api.State, submit *VkQueueSubmit, +func resolveCurrentRenderPass(ctx context.Context, s *api.GlobalState, submit *VkQueueSubmit, idx api.SubCmdIdx, lrp *RenderPassObject, subpass uint32) (*RenderPassObject, uint32) { if len(idx) == 0 { return lrp, subpass @@ -209,7 +209,7 @@ func resolveCurrentRenderPass(ctx context.Context, s *api.State, submit *VkQueue func rebuildCommandBuffer(ctx context.Context, cb CommandBuilder, commandBuffer *CommandBufferObject, - s *api.State, + s *api.GlobalState, idx api.SubCmdIdx, additionalCommands []interface{}) (VkCommandBuffer, []api.Cmd, []func()) { diff --git a/gapis/capture/capture.go b/gapis/capture/capture.go index c89b113379..217e81062f 100644 --- a/gapis/capture/capture.go +++ b/gapis/capture/capture.go @@ -77,7 +77,7 @@ func New(ctx context.Context, name string, header *Header, cmds []api.Cmd) (*pat // NewState returns a new, default-initialized State object built for the // capture held by the context. -func NewState(ctx context.Context) (*api.State, error) { +func NewState(ctx context.Context) (*api.GlobalState, error) { c, err := Resolve(ctx) if err != nil { return nil, err @@ -87,7 +87,7 @@ func NewState(ctx context.Context) (*api.State, error) { // NewState returns a new, default-initialized State object built for the // capture. -func (c *Capture) NewState() *api.State { +func (c *Capture) NewState() *api.GlobalState { freeList := memory.InvertMemoryRanges(c.Observed) interval.Remove(&freeList, interval.U64Span{Start: 0, End: value.FirstValidAddress}) return api.NewStateWithAllocator( diff --git a/gapis/extensions/unity/state_reset_grouper.go b/gapis/extensions/unity/state_reset_grouper.go index 9878019c6e..b47a021155 100644 --- a/gapis/extensions/unity/state_reset_grouper.go +++ b/gapis/extensions/unity/state_reset_grouper.go @@ -44,7 +44,7 @@ func (g *stateResetGrouper) flush(id api.CmdID) { } // Process considers the command for inclusion in the group. -func (g *stateResetGrouper) Process(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.State) { +func (g *stateResetGrouper) Process(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.GlobalState) { prev := g.prev g.prev = cmd diff --git a/gapis/replay/batch.go b/gapis/replay/batch.go index 0118a07908..67e2c5a165 100644 --- a/gapis/replay/batch.go +++ b/gapis/replay/batch.go @@ -176,11 +176,11 @@ func (m *Manager) execute( // adapter conforms to the the transformer.Writer interface, performing replay // writes on each command. type adapter struct { - state *api.State + state *api.GlobalState builder *builder.Builder } -func (w *adapter) State() *api.State { +func (w *adapter) State() *api.GlobalState { return w.state } diff --git a/gapis/replay/custom.go b/gapis/replay/custom.go index 6338c23d54..df877f225a 100644 --- a/gapis/replay/custom.go +++ b/gapis/replay/custom.go @@ -28,10 +28,10 @@ var _ = api.Cmd(Custom{}) // upon Replay(). type Custom struct { T uint64 // The thread ID - F func(ctx context.Context, s *api.State, b *builder.Builder) error + F func(ctx context.Context, s *api.GlobalState, b *builder.Builder) error } -func (c Custom) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *builder.Builder) error { +func (c Custom) Mutate(ctx context.Context, id api.CmdID, s *api.GlobalState, b *builder.Builder) error { if b == nil { return nil } @@ -39,11 +39,11 @@ func (c Custom) Mutate(ctx context.Context, id api.CmdID, s *api.State, b *build } // api.Cmd compliance -func (Custom) Caller() api.CmdID { return api.CmdNoID } -func (Custom) SetCaller(api.CmdID) {} -func (cmd Custom) Thread() uint64 { return cmd.T } -func (cmd Custom) SetThread(t uint64) { cmd.T = t } -func (Custom) CmdName() string { return "" } -func (Custom) API() api.API { return nil } -func (Custom) CmdFlags(context.Context, api.CmdID, *api.State) api.CmdFlags { return 0 } -func (Custom) Extras() *api.CmdExtras { return nil } +func (Custom) Caller() api.CmdID { return api.CmdNoID } +func (Custom) SetCaller(api.CmdID) {} +func (cmd Custom) Thread() uint64 { return cmd.T } +func (cmd Custom) SetThread(t uint64) { cmd.T = t } +func (Custom) CmdName() string { return "" } +func (Custom) API() api.API { return nil } +func (Custom) CmdFlags(context.Context, api.CmdID, *api.GlobalState) api.CmdFlags { return 0 } +func (Custom) Extras() *api.CmdExtras { return nil } diff --git a/gapis/resolve/cmdgrouper/cmdgrouper.go b/gapis/resolve/cmdgrouper/cmdgrouper.go index 30fddaf28e..ea13029a6b 100644 --- a/gapis/resolve/cmdgrouper/cmdgrouper.go +++ b/gapis/resolve/cmdgrouper/cmdgrouper.go @@ -32,7 +32,7 @@ type Group struct { // Grouper is the interface implemented by types that build groups. type Grouper interface { // Process considers the command for inclusion in the group. - Process(context.Context, api.CmdID, api.Cmd, *api.State) + Process(context.Context, api.CmdID, api.Cmd, *api.GlobalState) // Build returns the groups built and resets the state of the grouper. Build(end api.CmdID) []Group } @@ -40,7 +40,7 @@ type Grouper interface { // RunPred is the predicate used by the Run grouper. // Consecutive values returned by RunPred will be grouped together under the // group with name. -type RunPred func(cmd api.Cmd, s *api.State) (value interface{}, name string) +type RunPred func(cmd api.Cmd, s *api.GlobalState) (value interface{}, name string) // Run returns a grouper that groups commands together that form a run. func Run(pred RunPred) Grouper { @@ -49,14 +49,14 @@ func Run(pred RunPred) Grouper { // run is a grouper that groups consecutive runs of commands type run struct { - f func(cmd api.Cmd, s *api.State) (value interface{}, name string) + f func(cmd api.Cmd, s *api.GlobalState) (value interface{}, name string) start api.CmdID current interface{} name string out []Group } -func (g *run) Process(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.State) { +func (g *run) Process(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.GlobalState) { val, name := g.f(cmd, s) if val != g.current { if g.current != nil { @@ -87,7 +87,7 @@ type marker struct { out []Group } -func (g *marker) Process(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.State) { +func (g *marker) Process(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.GlobalState) { flags := cmd.CmdFlags(ctx, id, s) if flags.IsPushUserMarker() { g.push(ctx, id, cmd, s) @@ -109,7 +109,7 @@ func (g *marker) Build(end api.CmdID) []Group { // push enters a group at the specified id. // If the cmd implements api.Labeled then the group will use this label as the // group name. -func (g *marker) push(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.State) { +func (g *marker) push(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.GlobalState) { var name string if l, ok := cmd.(api.Labeled); ok { name = l.Label(ctx, s) diff --git a/gapis/resolve/command_tree.go b/gapis/resolve/command_tree.go index 59b1063c6e..7a5f7edda8 100644 --- a/gapis/resolve/command_tree.go +++ b/gapis/resolve/command_tree.go @@ -177,7 +177,7 @@ func (r *CommandTreeResolvable) Resolve(ctx context.Context) (interface{}, error if p.GroupByApi { groupers = append(groupers, cmdgrouper.Run( - func(cmd api.Cmd, s *api.State) (interface{}, string) { + func(cmd api.Cmd, s *api.GlobalState) (interface{}, string) { if api := cmd.API(); api != nil { return api.ID(), api.Name() } @@ -191,7 +191,7 @@ func (r *CommandTreeResolvable) Resolve(ctx context.Context) (interface{}, error noContextID = api.ContextID{} } groupers = append(groupers, cmdgrouper.Run( - func(cmd api.Cmd, s *api.State) (interface{}, string) { + func(cmd api.Cmd, s *api.GlobalState) (interface{}, string) { if api := cmd.API(); api != nil { if context := api.Context(s, cmd.Thread()); context != nil { return context.ID(), context.Name() @@ -203,7 +203,7 @@ func (r *CommandTreeResolvable) Resolve(ctx context.Context) (interface{}, error if p.GroupByThread { groupers = append(groupers, cmdgrouper.Run( - func(cmd api.Cmd, s *api.State) (interface{}, string) { + func(cmd api.Cmd, s *api.GlobalState) (interface{}, string) { thread := cmd.Thread() return thread, fmt.Sprintf("Thread: 0x%x", thread) })) diff --git a/gapis/resolve/contexts.go b/gapis/resolve/contexts.go index 5d0b08b6f6..37a9799b46 100644 --- a/gapis/resolve/contexts.go +++ b/gapis/resolve/contexts.go @@ -108,7 +108,7 @@ func (r *ContextListResolvable) Resolve(ctx context.Context) (interface{}, error api := c.API() ctxID := c.ID() id, err := database.Store(ctx, &InternalContext{ - Id: string(ctxID[:]), + Id: ctxID[:], Api: &path.API{Id: path.NewID(id.ID(api.ID()))}, Name: c.Name(), Priority: uint32(i), @@ -120,3 +120,9 @@ func (r *ContextListResolvable) Resolve(ctx context.Context) (interface{}, error } return out, nil } + +func (i *InternalContext) ID() api.ContextID { + var out api.ContextID + copy(out[:], i.Id) + return out +} diff --git a/gapis/resolve/dependencygraph/dependency_graph.go b/gapis/resolve/dependencygraph/dependency_graph.go index 3074ef886d..08db690fda 100644 --- a/gapis/resolve/dependencygraph/dependency_graph.go +++ b/gapis/resolve/dependencygraph/dependency_graph.go @@ -131,7 +131,7 @@ type DependencyGraphBehaviourProvider interface { } type BehaviourProvider interface { - GetBehaviourForAtom(context.Context, *api.State, api.CmdID, api.Cmd, *DependencyGraph) AtomBehaviour + GetBehaviourForAtom(context.Context, *api.GlobalState, api.CmdID, api.Cmd, *DependencyGraph) AtomBehaviour } func GetDependencyGraph(ctx context.Context) (*DependencyGraph, error) { diff --git a/gapis/resolve/dependencygraph/footprint.go b/gapis/resolve/dependencygraph/footprint.go index b7f463e705..23cf7b6c2a 100644 --- a/gapis/resolve/dependencygraph/footprint.go +++ b/gapis/resolve/dependencygraph/footprint.go @@ -182,7 +182,7 @@ type FootprintBuilderProvider interface { // FootprintBuilder incrementally builds Footprint one command by one command. type FootprintBuilder interface { - BuildFootprint(context.Context, *api.State, *Footprint, api.CmdID, api.Cmd) + BuildFootprint(context.Context, *api.GlobalState, *Footprint, api.CmdID, api.Cmd) } // GetFootprint returns a pointer to the resolved Footprint. diff --git a/gapis/resolve/filter.go b/gapis/resolve/filter.go index c701363a92..f60d45ce25 100644 --- a/gapis/resolve/filter.go +++ b/gapis/resolve/filter.go @@ -17,17 +17,16 @@ package resolve import ( "context" - "github.com/google/gapid/core/data/id" "github.com/google/gapid/gapis/api" "github.com/google/gapid/gapis/api/sync" "github.com/google/gapid/gapis/service/path" ) -type filter func(api.CmdID, api.Cmd, *api.State) bool +type filter func(api.CmdID, api.Cmd, *api.GlobalState) bool func buildFilter(ctx context.Context, p *path.Capture, f *path.CommandFilter, sd *sync.Data) (filter, error) { filters := []filter{ - func(id api.CmdID, cmd api.Cmd, s *api.State) bool { + func(id api.CmdID, cmd api.Cmd, s *api.GlobalState) bool { return !sd.Hidden.Contains(id) }, } @@ -36,12 +35,8 @@ func buildFilter(ctx context.Context, p *path.Capture, f *path.CommandFilter, sd if err != nil { return nil, err } - id, err := id.Parse(c.Id) - if err != nil { - return nil, err - } - ctxID := api.ContextID(id) - filters = append(filters, func(id api.CmdID, cmd api.Cmd, s *api.State) bool { + ctxID := c.ID() + filters = append(filters, func(id api.CmdID, cmd api.Cmd, s *api.GlobalState) bool { if api := cmd.API(); api != nil { if ctx := api.Context(s, cmd.Thread()); ctx != nil { return ctx.ID() == ctxID @@ -51,7 +46,7 @@ func buildFilter(ctx context.Context, p *path.Capture, f *path.CommandFilter, sd }) } if len(f.GetThreads()) > 0 { - filters = append(filters, func(id api.CmdID, cmd api.Cmd, s *api.State) bool { + filters = append(filters, func(id api.CmdID, cmd api.Cmd, s *api.GlobalState) bool { thread := cmd.Thread() for _, t := range f.Threads { if t == thread { @@ -61,7 +56,7 @@ func buildFilter(ctx context.Context, p *path.Capture, f *path.CommandFilter, sd return false }) } - return func(id api.CmdID, cmd api.Cmd, s *api.State) bool { + return func(id api.CmdID, cmd api.Cmd, s *api.GlobalState) bool { for _, f := range filters { if !f(id, cmd, s) { return false diff --git a/gapis/resolve/framebuffer_changes.go b/gapis/resolve/framebuffer_changes.go index 1c268f8b47..de80c7427c 100644 --- a/gapis/resolve/framebuffer_changes.go +++ b/gapis/resolve/framebuffer_changes.go @@ -57,7 +57,7 @@ func (r *FramebufferChangesResolvable) Resolve(ctx context.Context) (interface{} attachments: make([]framebufferAttachmentChanges, api.FramebufferAttachment_Color3+1), } - postCmdAndSubCmd := func(s *api.State, subcommandIndex api.SubCmdIdx, cmd api.Cmd) { + postCmdAndSubCmd := func(s *api.GlobalState, subcommandIndex api.SubCmdIdx, cmd api.Cmd) { api := cmd.API() idx := append([]uint64(nil), subcommandIndex...) for _, att := range allFramebufferAttachments { diff --git a/gapis/resolve/memory.go b/gapis/resolve/memory.go index 03ea366655..b6c809c7b6 100644 --- a/gapis/resolve/memory.go +++ b/gapis/resolve/memory.go @@ -84,12 +84,12 @@ func Memory(ctx context.Context, p *path.Memory) (*service.Memory, error) { if syncedApi, ok := lastCmd.API().(sync.SynchronizedAPI); len(fullCmdIdx) > 1 && ok { requestSubCmdIdx := api.SubCmdIdx(fullCmdIdx) syncedApi.MutateSubcommands(ctx, api.CmdID(cmdIdx), lastCmd, s, - func(s *api.State, subCommandIndex api.SubCmdIdx, cmd api.Cmd) { + func(s *api.GlobalState, subCommandIndex api.SubCmdIdx, cmd api.Cmd) { // Turn on OnRead and OnWrite if the subcommand to be executed is or // contained by the requested subcommand. shouldRecord = requestSubCmdIdx.Contains(subCommandIndex) }, // preSubCmdCallback - func(s *api.State, subCommandIndex api.SubCmdIdx, cmd api.Cmd) { + func(s *api.GlobalState, subCommandIndex api.SubCmdIdx, cmd api.Cmd) { // Turn off OnRead and OnWrite after each subcommand. shouldRecord = false }, //postSubCmdCallback diff --git a/gapis/resolve/requests_test.go b/gapis/resolve/requests_test.go index a9f770c414..663b0368c5 100644 --- a/gapis/resolve/requests_test.go +++ b/gapis/resolve/requests_test.go @@ -18,7 +18,6 @@ import "github.com/google/gapid/gapis/database" // Interface compliance tests var _ = []database.Resolvable{ - (*APIStateResolvable)(nil), (*CommandTreeResolvable)(nil), (*ContextListResolvable)(nil), (*FollowResolvable)(nil), @@ -33,4 +32,5 @@ var _ = []database.Resolvable{ (*ResourceMetaResolvable)(nil), (*ResourcesResolvable)(nil), (*SetResolvable)(nil), + (*StateResolvable)(nil), } diff --git a/gapis/resolve/resolvables.proto b/gapis/resolve/resolvables.proto index b05ce78eaa..e5f6e21a55 100644 --- a/gapis/resolve/resolvables.proto +++ b/gapis/resolve/resolvables.proto @@ -26,7 +26,7 @@ message ContextListResolvable { } message InternalContext { - string id = 1; + bytes id = 1; path.API api = 2; string name = 3; uint32 priority = 4; @@ -102,6 +102,10 @@ message ResourceMetaResolvable { } message GlobalStateResolvable { + path.GlobalState path = 1; +} + +message StateResolvable { path.State path = 1; } @@ -109,10 +113,6 @@ message SynchronizationResolvable { path.Capture capture = 1; } -message APIStateResolvable { - path.State path = 1; -} - message StateTreeResolvable { path.State path = 1; int32 array_group_size = 2; @@ -125,4 +125,5 @@ message SetResolvable { message FramebufferObservationResolvable { path.FramebufferObservation path = 1; -} \ No newline at end of file +} + diff --git a/gapis/resolve/resolve.go b/gapis/resolve/resolve.go index cd94c792ec..7f1cf469de 100644 --- a/gapis/resolve/resolve.go +++ b/gapis/resolve/resolve.go @@ -20,6 +20,7 @@ import ( "reflect" "github.com/google/gapid/core/image" + "github.com/google/gapid/core/math/sint" "github.com/google/gapid/core/os/device" "github.com/google/gapid/core/os/device/bind" "github.com/google/gapid/gapis/capture" @@ -215,7 +216,7 @@ func MapIndex(ctx context.Context, p *path.MapIndex) (interface{}, error) { m := reflect.ValueOf(obj) switch m.Kind() { case reflect.Map: - key, ok := convertMapKey(reflect.ValueOf(p.KeyValue()), m.Type().Key()) + key, ok := convert(reflect.ValueOf(p.KeyValue()), m.Type().Key()) if !ok { return nil, &service.ErrInvalidPath{ Reason: messages.ErrIncorrectMapKeyType( @@ -288,6 +289,8 @@ func ResolveInternal(ctx context.Context, p path.Node) (interface{}, error) { return FramebufferObservation(ctx, p) case *path.Field: return Field(ctx, p) + case *path.GlobalState: + return GlobalState(ctx, p) case *path.ImageInfo: return ImageInfo(ctx, p) case *path.MapIndex: @@ -309,7 +312,7 @@ func ResolveInternal(ctx context.Context, p path.Node) (interface{}, error) { case *path.Slice: return Slice(ctx, p) case *path.State: - return APIState(ctx, p) + return State(ctx, p) case *path.StateTree: return StateTree(ctx, p) case *path.StateTreeNode: @@ -336,7 +339,10 @@ func typename(t reflect.Type) string { } } -func convertMapKey(val reflect.Value, ty reflect.Type) (reflect.Value, bool) { +func convert(val reflect.Value, ty reflect.Type) (reflect.Value, bool) { + if !val.IsValid() { + return reflect.Zero(ty), true + } valTy := val.Type() if valTy == ty { return val, true @@ -344,18 +350,20 @@ func convertMapKey(val reflect.Value, ty reflect.Type) (reflect.Value, bool) { if valTy.ConvertibleTo(ty) { return val.Convert(ty), true } - return val, false -} - -func convert(val reflect.Value, ty reflect.Type) (reflect.Value, bool) { - if !val.IsValid() { - return reflect.Zero(ty), true - } - if valTy := val.Type(); valTy != ty { - if !valTy.ConvertibleTo(ty) { - return val, false + // slice -> array + if valTy.Kind() == reflect.Slice && ty.Kind() == reflect.Array { + if valTy.Elem().ConvertibleTo(ty.Elem()) { + c := sint.Min(val.Len(), ty.Len()) + out := reflect.New(ty).Elem() + for i := 0; i < c; i++ { + v, ok := convert(val.Index(i), ty.Elem()) + if !ok { + return val, false + } + out.Index(i).Set(v) + } + return out, true } - val = val.Convert(ty) } - return val, true + return val, false } diff --git a/gapis/resolve/set.go b/gapis/resolve/set.go index e5d7121277..b8ae9002fd 100644 --- a/gapis/resolve/set.go +++ b/gapis/resolve/set.go @@ -258,7 +258,7 @@ func change(ctx context.Context, p path.Node, val interface{}) (path.Node, error Path: p.Path(), } } - key, ok := convertMapKey(reflect.ValueOf(p.KeyValue()), m.Type().Key()) + key, ok := convert(reflect.ValueOf(p.KeyValue()), m.Type().Key()) if !ok { return nil, &service.ErrInvalidPath{ Reason: messages.ErrIncorrectMapKeyType( diff --git a/gapis/resolve/state.go b/gapis/resolve/state.go index 314c6bbfab..988e36ebe5 100644 --- a/gapis/resolve/state.go +++ b/gapis/resolve/state.go @@ -16,7 +16,6 @@ package resolve import ( "context" - "fmt" "github.com/google/gapid/gapis/api" "github.com/google/gapid/gapis/api/sync" @@ -27,23 +26,19 @@ import ( "github.com/google/gapid/gapis/service/path" ) -// GlobalState resolves the global *api.State at a requested point in a +// GlobalState resolves the global *api.GlobalState at a requested point in a // capture. -func GlobalState(ctx context.Context, p *path.State) (*api.State, error) { +func GlobalState(ctx context.Context, p *path.GlobalState) (*api.GlobalState, error) { obj, err := database.Build(ctx, &GlobalStateResolvable{p}) if err != nil { return nil, err } - return obj.(*api.State), nil + return obj.(*api.GlobalState), nil } -// APIState resolves the specific API state at a requested point in a capture. -func APIState(ctx context.Context, p *path.State) (interface{}, error) { - obj, err := database.Build(ctx, &APIStateResolvable{p}) - if err != nil { - return nil, err - } - return obj, nil +// State resolves the specific API state at a requested point in a capture. +func State(ctx context.Context, p *path.State) (interface{}, error) { + return database.Build(ctx, &StateResolvable{p}) } // Resolve implements the database.Resolver interface. @@ -80,47 +75,62 @@ func (r *GlobalStateResolvable) Resolve(ctx context.Context) (interface{}, error } // Resolve implements the database.Resolver interface. -func (r *APIStateResolvable) Resolve(ctx context.Context) (interface{}, error) { +func (r *StateResolvable) Resolve(ctx context.Context) (interface{}, error) { ctx = capture.Put(ctx, r.Path.After.Capture) - cmdIdx := r.Path.After.Indices[0] - if len(r.Path.After.Indices) > 1 { - return nil, fmt.Errorf("Subcommands currently not supported for api state") // TODO: Subcommands - } - cmds, err := NCmds(ctx, r.Path.After.Capture, cmdIdx+1) + obj, _, _, err := state(ctx, r.Path) + return obj, err +} + +func state(ctx context.Context, p *path.State) (interface{}, path.Node, api.ID, error) { + cmd, err := Cmd(ctx, p.After) if err != nil { - return nil, err + return nil, nil, api.ID{}, err } - return apiState(ctx, cmds, r.Path) -} -func apiState(ctx context.Context, cmds []api.Cmd, p *path.State) (interface{}, error) { - cmdIdx := p.After.Indices[0] - if len(p.After.Indices) > 1 { - return nil, fmt.Errorf("Subcommands currently not supported for api state") // TODO: Subcommands + a := cmd.API() + if a == nil { + return nil, nil, api.ID{}, &service.ErrDataUnavailable{Reason: messages.ErrStateUnavailable()} } - if count := uint64(len(cmds)); cmdIdx >= count { - return nil, errPathOOB(cmdIdx, "Index", 0, count-1, p) + + g, err := GlobalState(ctx, p.After.GlobalStateAfter()) + if err != nil { + return nil, nil, api.ID{}, err } - a := cmds[cmdIdx].API() - if a == nil { - return nil, &service.ErrDataUnavailable{Reason: messages.ErrStateUnavailable()} + + state := g.APIs[a.ID()] + if state == nil { + return nil, nil, api.ID{}, &service.ErrDataUnavailable{Reason: messages.ErrStateUnavailable()} } - s, err := capture.NewState(ctx) + + root, err := state.Root(ctx, p) if err != nil { - return nil, err + return nil, nil, api.ID{}, err + } + if root == nil { + return nil, nil, api.ID{}, &service.ErrDataUnavailable{Reason: messages.ErrStateUnavailable()} } - err = api.ForeachCmd(ctx, cmds[:cmdIdx+1], func(ctx context.Context, id api.CmdID, cmd api.Cmd) error { - cmd.Mutate(ctx, id, s, nil) - return nil + // Transform the State path node to a GlobalState node to prevent the + // object load recursing back into this function. + abs := path.Transform(root, func(n path.Node) path.Node { + switch n := n.(type) { + case *path.State: + return APIStateAfter(p.After, a.ID()) + default: + return n + } }) + + obj, err := Get(ctx, abs.Path()) if err != nil { - return nil, err + return nil, nil, api.ID{}, err } - res, found := s.APIs[a] - if !found { - return nil, &service.ErrDataUnavailable{Reason: messages.ErrStateUnavailable()} - } - return res, nil + return obj, abs, a.ID(), nil +} + +// APIStateAfter returns an absolute path to the API state after c. +func APIStateAfter(c *path.Command, a api.ID) path.Node { + p := &path.GlobalState{After: c} + return p.Field("APIs").MapIndex(a) } diff --git a/gapis/resolve/state_tree.go b/gapis/resolve/state_tree.go index 00fcc04e9d..e593c65a7a 100644 --- a/gapis/resolve/state_tree.go +++ b/gapis/resolve/state_tree.go @@ -25,7 +25,6 @@ import ( "github.com/google/gapid/core/data/slice" "github.com/google/gapid/core/math/u64" "github.com/google/gapid/gapis/api" - "github.com/google/gapid/gapis/capture" "github.com/google/gapid/gapis/database" "github.com/google/gapid/gapis/memory" "github.com/google/gapid/gapis/service" @@ -35,7 +34,7 @@ import ( // StateTree resolves the specified state tree path. func StateTree(ctx context.Context, c *path.StateTree) (*service.StateTree, error) { - id, err := database.Store(ctx, &StateTreeResolvable{c.After.StateAfter(), c.ArrayGroupSize}) + id, err := database.Store(ctx, &StateTreeResolvable{c.State, c.ArrayGroupSize}) if err != nil { return nil, err } @@ -45,10 +44,11 @@ func StateTree(ctx context.Context, c *path.StateTree) (*service.StateTree, erro } type stateTree struct { - state *api.State - root *stn - api *path.API - groupLimit uint64 + globalState *api.GlobalState + state interface{} + root *stn + api *path.API + groupLimit uint64 } // needsSubgrouping returns true if the child count exceeds the group limit and @@ -136,22 +136,10 @@ func stateTreeNode(ctx context.Context, tree *stateTree, p *path.StateTreeNode) return node.service(ctx, tree), nil } -// stateMemberPath returns the child path nodes of the *path.State in n. -// If n does not contain a *path.State then nil is returned. -func stateMemberPath(n path.Node) []path.Node { - p := path.ToList(n) - for i, n := range p { - if _, ok := n.(*path.State); ok { - return p[i+1:] - } - } - return nil -} - func stateTreeNodePath(ctx context.Context, tree *stateTree, p path.Node) ([]uint64, error) { n := tree.root indices := []uint64{} - for _, p := range stateMemberPath(p) { + for { ci := n.findByPath(ctx, p, tree) if ci == nil { break @@ -191,7 +179,7 @@ func (n *stn) index(ctx context.Context, i uint64, tree *stateTree) (*stn, error func (n *stn) findByPath(ctx context.Context, p path.Node, tree *stateTree) []uint64 { n.buildChildren(ctx, tree) for i, c := range n.children { - if shallowPathsEqual(p, c.path) { + if path.HasRoot(p, c.path) { return []uint64{uint64(i)} } } @@ -205,28 +193,6 @@ func (n *stn) findByPath(ctx context.Context, p path.Node, tree *stateTree) []ui return nil } -func shallowPathsEqual(a, b path.Node) bool { - switch a := a.(type) { - case *path.Field: - if b, ok := b.(*path.Field); ok { - return a.Name == b.Name - } - case *path.MapIndex: - if b, ok := b.(*path.MapIndex); ok { - return a.KeyValue() == b.KeyValue() - } - case *path.ArrayIndex: - if b, ok := b.(*path.ArrayIndex); ok { - return a.Index == b.Index - } - case *path.Slice: - if b, ok := b.(*path.Slice); ok { - return a.Start == b.Start && a.End == b.End - } - } - return false -} - func (n *stn) buildChildren(ctx context.Context, tree *stateTree) { n.mutex.Lock() defer n.mutex.Unlock() @@ -245,7 +211,7 @@ func (n *stn) buildChildren(ctx context.Context, tree *stateTree) { s, e := subgroupRange(tree.groupLimit, size, i) children = append(children, &stn{ name: fmt.Sprintf("[%d - %d]", n.subgroupOffset+s, n.subgroupOffset+e-1), - value: reflect.ValueOf(slice.ISlice(s, e, tree.state.MemoryLayout)), + value: reflect.ValueOf(slice.ISlice(s, e, tree.globalState.MemoryLayout)), path: path.NewSlice(s, e-1, n.path), isSubgroup: true, subgroupOffset: n.subgroupOffset + s, @@ -253,8 +219,8 @@ func (n *stn) buildChildren(ctx context.Context, tree *stateTree) { } } else { for i, c := uint64(0), slice.Count(); i < c; i++ { - ptr := slice.IIndex(i, tree.state.MemoryLayout) - el, err := memory.LoadPointer(ctx, ptr, tree.state.Memory, tree.state.MemoryLayout) + ptr := slice.IIndex(i, tree.globalState.MemoryLayout) + el, err := memory.LoadPointer(ctx, ptr, tree.globalState.Memory, tree.globalState.MemoryLayout) if err != nil { panic(err) } @@ -339,7 +305,7 @@ func (n *stn) service(ctx context.Context, tree *stateTree) *service.StateTreeNo } func isFieldVisible(f reflect.StructField) bool { - return f.PkgPath == "" && f.Tag.Get("nobox") != "true" + return f.PkgPath == "" && f.Tag.Get("hidden") != "true" } func stateValuePreview(v reflect.Value) (*box.Value, bool) { @@ -381,26 +347,22 @@ func stateValuePreview(v reflect.Value) (*box.Value, bool) { // Resolve builds and returns a *StateTree for the path.StateTreeNode. // Resolve implements the database.Resolver interface. func (r *StateTreeResolvable) Resolve(ctx context.Context) (interface{}, error) { - state, err := GlobalState(ctx, r.Path) + globalState, err := GlobalState(ctx, r.Path.After.GlobalStateAfter()) if err != nil { return nil, err } - c, err := capture.ResolveFromPath(ctx, r.Path.After.Capture) + + rootObj, rootPath, apiID, err := state(ctx, r.Path) if err != nil { return nil, err } - cmdIdx := r.Path.After.Indices[0] - api := c.Commands[cmdIdx].API() - if api == nil { - return nil, fmt.Errorf("Command has no API") - } - apiState := state.APIs[api] - apiPath := &path.API{Id: path.NewID(id.ID(api.ID()))} + apiPath := &path.API{Id: path.NewID(id.ID(apiID))} + root := &stn{ name: "root", - value: deref(reflect.ValueOf(apiState)), - path: r.Path, + value: deref(reflect.ValueOf(rootObj)), + path: rootPath, } - return &stateTree{state, root, apiPath, uint64(r.ArrayGroupSize)}, nil + return &stateTree{globalState, rootObj, root, apiPath, uint64(r.ArrayGroupSize)}, nil } diff --git a/gapis/resolve/state_tree_test.go b/gapis/resolve/state_tree_test.go index b7916cbc04..0ae603fd83 100644 --- a/gapis/resolve/state_tree_test.go +++ b/gapis/resolve/state_tree_test.go @@ -165,12 +165,12 @@ func TestStateTreeNode(t *testing.T) { } ctx = capture.Put(ctx, c) rootPath := c.Command(0).StateAfter() - state, err := capture.NewState(ctx) + gs, err := capture.NewState(ctx) if err != nil { panic(err) } tree := &stateTree{ - state: state, + globalState: gs, root: &stn{ name: "root", value: reflect.ValueOf(testState), @@ -182,7 +182,7 @@ func TestStateTreeNode(t *testing.T) { root := &path.StateTreeNode{Indices: []uint64{}} // Write some data to 0x1000. - e := tree.state.MemoryEncoder(memory.ApplicationPool, memory.Range{Base: 0x1000, Size: 0x8000}) + e := gs.MemoryEncoder(memory.ApplicationPool, memory.Range{Base: 0x1000, Size: 0x8000}) for i := 0; i < 0x1000; i++ { e.I64(int64(i * 10)) } diff --git a/gapis/service/path/CMakeFiles.cmake b/gapis/service/path/CMakeFiles.cmake index f14383fe9f..b94f31fb6f 100644 --- a/gapis/service/path/CMakeFiles.cmake +++ b/gapis/service/path/CMakeFiles.cmake @@ -24,6 +24,7 @@ set(files path.go path.pb.go path.proto + transform.go validate.go ) set(dirs diff --git a/gapis/service/path/id.go b/gapis/service/path/id.go index 3d69c6dbb5..33bd0e8705 100644 --- a/gapis/service/path/id.go +++ b/gapis/service/path/id.go @@ -16,7 +16,6 @@ package path import ( "encoding/hex" - "fmt" "github.com/google/gapid/core/data/id" diff --git a/gapis/service/path/path.go b/gapis/service/path/path.go index 590fa99eb6..77e603c04f 100644 --- a/gapis/service/path/path.go +++ b/gapis/service/path/path.go @@ -17,8 +17,10 @@ package path import ( "fmt" "math" + "reflect" "strings" + "github.com/golang/protobuf/proto" "github.com/google/gapid/core/data/id" "github.com/google/gapid/core/data/protoutil" "github.com/google/gapid/core/data/slice" @@ -35,6 +37,9 @@ type Node interface { // If this path is a root, then Base returns nil. Parent() Node + // SetParent sets the path that this derives from. + SetParent(Node) + // Path returns this path node as a path. Path() *Any @@ -68,6 +73,7 @@ func (n *Device) Path() *Any { return &Any{&Any_Device{n}} } func (n *Events) Path() *Any { return &Any{&Any_Events{n}} } func (n *FramebufferObservation) Path() *Any { return &Any{&Any_Fbo{n}} } func (n *Field) Path() *Any { return &Any{&Any_Field{n}} } +func (n *GlobalState) Path() *Any { return &Any{&Any_GlobalState{n}} } func (n *ImageInfo) Path() *Any { return &Any{&Any_ImageInfo{n}} } func (n *MapIndex) Path() *Any { return &Any{&Any_MapIndex{n}} } func (n *Memory) Path() *Any { return &Any{&Any_Memory{n}} } @@ -101,6 +107,7 @@ func (n Device) Parent() Node { return nil } func (n Events) Parent() Node { return n.Capture } func (n FramebufferObservation) Parent() Node { return n.Command } func (n Field) Parent() Node { return oneOfNode(n.Struct) } +func (n GlobalState) Parent() Node { return n.After } func (n ImageInfo) Parent() Node { return nil } func (n MapIndex) Parent() Node { return oneOfNode(n.Map) } func (n Memory) Parent() Node { return n.After } @@ -112,11 +119,38 @@ func (n Resources) Parent() Node { return n.Capture } func (n Result) Parent() Node { return n.Command } func (n Slice) Parent() Node { return oneOfNode(n.Array) } func (n State) Parent() Node { return n.After } -func (n StateTree) Parent() Node { return n.After } +func (n StateTree) Parent() Node { return n.State } func (n StateTreeNode) Parent() Node { return nil } func (n StateTreeNodeForPath) Parent() Node { return nil } func (n Thumbnail) Parent() Node { return oneOfNode(n.Object) } +func (n *API) SetParent(p Node) {} +func (n *Blob) SetParent(p Node) {} +func (n *Capture) SetParent(p Node) {} +func (n *ConstantSet) SetParent(p Node) { n.Api, _ = p.(*API) } +func (n *Command) SetParent(p Node) { n.Capture, _ = p.(*Capture) } +func (n *Commands) SetParent(p Node) { n.Capture, _ = p.(*Capture) } +func (n *CommandTree) SetParent(p Node) { n.Capture, _ = p.(*Capture) } +func (n *CommandTreeNode) SetParent(p Node) {} +func (n *CommandTreeNodeForCommand) SetParent(p Node) { n.Command, _ = p.(*Command) } +func (n *Context) SetParent(p Node) { n.Capture, _ = p.(*Capture) } +func (n *Contexts) SetParent(p Node) { n.Capture, _ = p.(*Capture) } +func (n *Device) SetParent(p Node) {} +func (n *Events) SetParent(p Node) { n.Capture, _ = p.(*Capture) } +func (n *FramebufferObservation) SetParent(p Node) { n.Command, _ = p.(*Command) } +func (n *GlobalState) SetParent(p Node) { n.After, _ = p.(*Command) } +func (n *ImageInfo) SetParent(p Node) {} +func (n *Memory) SetParent(p Node) { n.After, _ = p.(*Command) } +func (n *Parameter) SetParent(p Node) { n.Command, _ = p.(*Command) } +func (n *Report) SetParent(p Node) { n.Capture, _ = p.(*Capture) } +func (n *ResourceData) SetParent(p Node) { n.After, _ = p.(*Command) } +func (n *Resources) SetParent(p Node) { n.Capture, _ = p.(*Capture) } +func (n *Result) SetParent(p Node) { n.Command, _ = p.(*Command) } +func (n *State) SetParent(p Node) { n.After, _ = p.(*Command) } +func (n *StateTree) SetParent(p Node) { n.State, _ = p.(*State) } +func (n *StateTreeNode) SetParent(p Node) {} +func (n *StateTreeNodeForPath) SetParent(p Node) {} + // Format implements fmt.Formatter to print the version. func (n ArrayIndex) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v[%v]", n.Parent(), n.Index) @@ -152,7 +186,7 @@ func (n Commands) Format(f fmt.State, c rune) { } // Format implements fmt.Formatter to print the version. -func (n CommandTree) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.command-tree") } +func (n CommandTree) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.command-tree", n.Capture) } // Format implements fmt.Formatter to print the version. func (n CommandTreeNode) Format(f fmt.State, c rune) { @@ -174,11 +208,14 @@ func (n Contexts) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.contexts", n. func (n Device) Format(f fmt.State, c rune) { fmt.Fprintf(f, "device<%x>", n.Id) } // Format implements fmt.Formatter to print the version. -func (n Events) Format(f fmt.State, c rune) { fmt.Fprintf(f, ".events", n.Parent()) } +func (n Events) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.events", n.Parent()) } // Format implements fmt.Formatter to print the version. func (n Field) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.%v", n.Parent(), n.Name) } +// Format implements fmt.Formatter to print the version. +func (n GlobalState) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.global-state", n.Parent()) } + // Format implements fmt.Formatter to print the version. func (n ImageInfo) Format(f fmt.State, c rune) { fmt.Fprintf(f, "image-info<%x>", n.Id) } @@ -214,10 +251,12 @@ func (n Slice) Format(f fmt.State, c rune) { } // Format implements fmt.Formatter to print the version. -func (n State) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.state-after", n.Parent()) } +func (n State) Format(f fmt.State, c rune) { + fmt.Fprintf(f, "%v.state", n.Parent(), n.Context) +} // Format implements fmt.Formatter to print the version. -func (n StateTree) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.state-tree") } +func (n StateTree) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.tree", n.State) } // Format implements fmt.Formatter to print the version. func (n StateTreeNode) Format(f fmt.State, c rune) { @@ -232,8 +271,33 @@ func (n StateTreeNodeForPath) Format(f fmt.State, c rune) { // Format implements fmt.Formatter to print the version. func (n Thumbnail) Format(f fmt.State, c rune) { fmt.Fprintf(f, "%v.thumbnail", n.Parent()) } +func (n *As) SetParent(p Node) { + switch p := p.(type) { + case nil: + n.From = nil + case *Field: + n.From = &As_Field{p} + case *Slice: + n.From = &As_Slice{p} + case *ArrayIndex: + n.From = &As_ArrayIndex{p} + case *MapIndex: + n.From = &As_MapIndex{p} + case *ImageInfo: + n.From = &As_ImageInfo{p} + case *ResourceData: + n.From = &As_ResourceData{p} + case *Mesh: + n.From = &As_Mesh{p} + default: + panic(fmt.Errorf("Cannot set As.From to %T", p)) + } +} + func (n *ArrayIndex) SetParent(p Node) { switch p := p.(type) { + case nil: + n.Array = nil case *Field: n.Array = &ArrayIndex_Field{p} case *Slice: @@ -253,8 +317,12 @@ func (n *ArrayIndex) SetParent(p Node) { func (n *Field) SetParent(p Node) { switch p := p.(type) { + case nil: + n.Struct = nil case *Field: n.Struct = &Field_Field{p} + case *GlobalState: + n.Struct = &Field_GlobalState{p} case *Slice: n.Struct = &Field_Slice{p} case *ArrayIndex: @@ -272,6 +340,8 @@ func (n *Field) SetParent(p Node) { func (n *MapIndex) SetParent(p Node) { switch p := p.(type) { + case nil: + n.Map = nil case *Field: n.Map = &MapIndex_Field{p} case *Slice: @@ -289,8 +359,23 @@ func (n *MapIndex) SetParent(p Node) { } } +func (n *Mesh) SetParent(p Node) { + switch p := p.(type) { + case nil: + n.Object = nil + case *Command: + n.Object = &Mesh_Command{p} + case *CommandTreeNode: + n.Object = &Mesh_CommandTreeNode{p} + default: + panic(fmt.Errorf("Cannot set Mesh.Object to %T", p)) + } +} + func (n *Slice) SetParent(p Node) { switch p := p.(type) { + case nil: + n.Array = nil case *Field: n.Array = &Slice_Field{p} case *Slice: @@ -306,6 +391,21 @@ func (n *Slice) SetParent(p Node) { } } +func (n *Thumbnail) SetParent(p Node) { + switch p := p.(type) { + case nil: + n.Object = nil + case *ResourceData: + n.Object = &Thumbnail_Resource{p} + case *Command: + n.Object = &Thumbnail_Command{p} + case *CommandTreeNode: + n.Object = &Thumbnail_CommandTreeNode{p} + default: + panic(fmt.Errorf("Cannot set Thumbnail.Object to %T", p)) + } +} + func oneOfNode(v interface{}) Node { return protoutil.OneOf(v).(Node) } @@ -501,16 +601,16 @@ func (n *Command) Mesh(faceted bool) *Mesh { } } +// GlobalStateAfter returns the path node to the state after this command. +func (n *Command) GlobalStateAfter() *GlobalState { + return &GlobalState{After: n} +} + // StateAfter returns the path node to the state after this command. func (n *Command) StateAfter() *State { return &State{After: n} } -// StateTreeAfter returns the path node to the state tree after this command. -func (n *Command) StateTreeAfter() *StateTree { - return &StateTree{After: n} -} - // First returns the path to the first command. func (n *Commands) First() *Command { return &Command{Capture: n.Capture, Indices: n.From} @@ -539,6 +639,12 @@ func (n *Command) Result() *Result { return &Result{Command: n} } +// Tree returns the path node to the state tree for this state. +func (n *State) Tree() *StateTree { + return &StateTree{State: n} +} + +func (n *GlobalState) Field(name string) *Field { return NewField(name, n) } func (n *State) Field(name string) *Field { return NewField(name, n) } func (n *Parameter) ArrayIndex(i uint64) *ArrayIndex { return NewArrayIndex(i, n) } func (n *Parameter) Field(name string) *Field { return NewField(name, n) } @@ -584,3 +690,26 @@ func ToList(n Node) []Node { slice.Reverse(out) return out } + +// HasRoot returns true iff p starts with root, using equal as the node +// comparision function. +func HasRoot(p, root Node) (res bool) { + a, b := ToList(p), ToList(root) + if len(b) > len(a) { + return false + } + for i, n := range b { + if !ShallowEqual(n, a[i]) { + return false + } + } + return true +} + +// ShallowEqual returns true if paths a and b are equal (ignoring parents). +func ShallowEqual(a, b Node) bool { + a, b = proto.Clone(a.(proto.Message)).(Node), proto.Clone(b.(proto.Message)).(Node) + a.SetParent(nil) + b.SetParent(nil) + return reflect.DeepEqual(a, b) +} diff --git a/gapis/service/path/path.proto b/gapis/service/path/path.proto index 2e4a7c8c92..5f0c5d47a9 100644 --- a/gapis/service/path/path.proto +++ b/gapis/service/path/path.proto @@ -42,21 +42,22 @@ message Any { Events events = 15; FramebufferObservation fbo = 16; Field field = 17; - ImageInfo image_info = 18; - MapIndex map_index = 19; - Memory memory = 20; - Mesh mesh = 21; - Parameter parameter = 22; - Report report = 23; - ResourceData resource_data = 24; - Resources resources = 25; - Result result = 26; - Slice slice = 27; - State state = 28; - StateTree state_tree = 29; - StateTreeNode state_tree_node = 30; - StateTreeNodeForPath state_tree_node_for_path = 31; - Thumbnail thumbnail = 32; + GlobalState global_state = 18; + ImageInfo image_info = 19; + MapIndex map_index = 20; + Memory memory = 21; + Mesh mesh = 22; + Parameter parameter = 23; + Report report = 24; + ResourceData resource_data = 25; + Resources resources = 26; + Result result = 27; + Slice slice = 28; + State state = 29; + StateTree state_tree = 30; + StateTreeNode state_tree_node = 31; + StateTreeNodeForPath state_tree_node_for_path = 32; + Thumbnail thumbnail = 33; } } @@ -210,7 +211,8 @@ message Field { ArrayIndex array_index = 4; MapIndex map_index = 5; State state = 6; - Parameter parameter = 7; + GlobalState global_state = 7; + Parameter parameter = 8; } } @@ -364,15 +366,24 @@ message Slice { } } -// State is a path to the state at a point in a capture. +// State is a path to a subset of the GlobalState at a point in a capture. message State { Command after = 1; + // If non-nil, then the state is filtered to the specified context. + ID context = 2; +} + +// GlobalState is an path node to the absolute global state after a specfied +// command. GlobalStates are used where stable paths are required, such as +// locating state tree nodes. +message GlobalState { + path.Command after = 1; } // StateTree is a path to a hierarchy of state tree nodes. // Resolves to a service.StateTree. message StateTree { - Command after = 1; + State state = 1; // If positive, expanded arrays/slices with more elements than this limit // will be restructured to have up to two extra levels of tree nodes, each // with at most this many children. If the array has more elements than this diff --git a/gapis/service/path/transform.go b/gapis/service/path/transform.go new file mode 100644 index 0000000000..df647b77a8 --- /dev/null +++ b/gapis/service/path/transform.go @@ -0,0 +1,24 @@ +// Copyright (C) 2017 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package path + +// Transform transforms each of the nodes in the chain using the function f. +func Transform(n Node, f func(Node) Node) Node { + n = f(n) + if p := n.Parent(); p != nil { + n.SetParent(Transform(p, f)) + } + return n +} diff --git a/gapis/service/path/validate.go b/gapis/service/path/validate.go index 14fc1dab24..2b41923927 100644 --- a/gapis/service/path/validate.go +++ b/gapis/service/path/validate.go @@ -16,12 +16,27 @@ package path import ( "fmt" + "reflect" "github.com/google/gapid/core/data/protoutil" ) -func checkNotNilAndValidate(n Node, f interface{}, name string) error { +func isNil(f interface{}) bool { if f == nil { + return true + } + v := reflect.ValueOf(f) + for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { + if v.IsNil() { + return true + } + v = v.Elem() + } + return false +} + +func checkNotNilAndValidate(n Node, f interface{}, name string) error { + if isNil(f) { return fmt.Errorf("Invalid path '%v': %v must not be nil", n, name) } if fn, ok := f.(Node); ok { @@ -180,6 +195,11 @@ func (n *Field) Validate() error { ) } +// Validate checks the path is valid. +func (n *GlobalState) Validate() error { + return checkNotNilAndValidate(n, n.After, "after") +} + // Validate checks the path is valid. func (n *ImageInfo) Validate() error { return checkNotNilAndValidate(n, n.Id, "id") @@ -246,7 +266,7 @@ func (n *State) Validate() error { // Validate checks the path is valid. func (n *StateTree) Validate() error { - return checkNotNilAndValidate(n, n.After, "after") + return checkNotNilAndValidate(n, n.State, "state") } // Validate checks the path is valid. diff --git a/test/integration/replay/gles/gles_test.go b/test/integration/replay/gles/gles_test.go index d1b5a3da75..00026ce916 100644 --- a/test/integration/replay/gles/gles_test.go +++ b/test/integration/replay/gles/gles_test.go @@ -154,7 +154,7 @@ type Fixture struct { mgr *replay.Manager device bind.Device memoryLayout *device.MemoryLayout - s *api.State + s *api.GlobalState nextID uint32 cb gles.CommandBuilder } diff --git a/test/integration/replay/gles/samples/builder.go b/test/integration/replay/gles/samples/builder.go index 23a9d8c166..67a85bab3f 100644 --- a/test/integration/replay/gles/samples/builder.go +++ b/test/integration/replay/gles/samples/builder.go @@ -26,7 +26,7 @@ import ( type builder struct { gles.CommandBuilder cmds []api.Cmd - state *api.State + state *api.GlobalState lastID uint }