Skip to content

Commit

Permalink
Show memory observations of the initial call for Vulkan Subcommands (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Qining authored Oct 18, 2017
1 parent 7a26dc5 commit 4da51fa
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 55 deletions.
17 changes: 17 additions & 0 deletions gapis/api/gvr/gvr.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,23 @@ func (API) ResolveSynchronization(ctx context.Context, d *sync.Data, c *path.Cap
return nil
}

// FlattenSubcommandIdx flattens grouped ids to their flattened linear ids if possible.
func (API) FlattenSubcommandIdx(idx api.SubCmdIdx, data *sync.Data, unused bool) (api.CmdID, bool) {
sg, ok := data.SubcommandReferences[api.CmdID(idx[0])]
if !ok {
return api.CmdID(0), false
}
for _, v := range sg {
if v.Index.Equals(idx[1:]) {
if v.IsCallerGroup {
return v.GeneratingCmd, true
}
break
}
}
return api.CmdID(0), false
}

// 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.GlobalState,
Expand Down
40 changes: 19 additions & 21 deletions gapis/api/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ type SynchronizedAPI interface {
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

// FlattenSubcommandIdx returns the flatten command id for the subcommand
// specified by the given SubCmdIdx. If flattening succeeded, the flatten
// command id and true will be returned, otherwise, zero and false will be
// returned.
FlattenSubcommandIdx(idx api.SubCmdIdx, d *Data, initialCall bool) (api.CmdID, bool)
}

type writer struct {
Expand All @@ -61,27 +67,10 @@ func (s *writer) MutateAndWrite(ctx context.Context, id api.CmdID, cmd api.Cmd)
s.cmds = append(s.cmds, cmd)
}

// calleeCmdID flattens grouped ids to their flattened linear ids if possible.
func calleeCmdID(idx api.SubCmdIdx, data *Data) api.CmdID {
sg, ok := data.SubcommandReferences[api.CmdID(idx[0])]
if !ok {
return 0
}
for _, v := range sg {
if v.Index.Equals(idx[1:]) {
if v.IsCallerGroup {
return v.GeneratingCmd
}
break
}
}
return api.CmdID(0)
}

// MutationCmdsFor returns a list of command that represent the correct
// mutations to have the state for all commands before and including the given
// index.
func MutationCmdsFor(ctx context.Context, c *path.Capture, data *Data, cmds []api.Cmd, id api.CmdID, subindex []uint64) ([]api.Cmd, error) {
func MutationCmdsFor(ctx context.Context, c *path.Capture, data *Data, cmds []api.Cmd, id api.CmdID, subindex api.SubCmdIdx, initialCall bool) ([]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.
Expand All @@ -93,9 +82,18 @@ func MutationCmdsFor(ctx context.Context, c *path.Capture, data *Data, cmds []ap
fullCommand := api.SubCmdIdx{uint64(id)}
fullCommand = append(fullCommand, subindex...)

if newIdx := calleeCmdID(fullCommand, data); newIdx != 0 {
id = newIdx
subindex = []uint64{}
lastCmd := cmds[len(cmds)-1]
if api.CmdID(len(cmds)) > id {
lastCmd = cmds[id]
}

if sync, ok := lastCmd.API().(SynchronizedAPI); ok {
// For Vulkan, when preparing the mutation for memory view, we need to get
// the initial call ID for the requesting subcommand.
if flattenIdx, ok := sync.FlattenSubcommandIdx(fullCommand, data, initialCall); ok {
id = flattenIdx
subindex = api.SubCmdIdx{}
}
}

terminators := make([]transform.Terminator, 0)
Expand Down
2 changes: 1 addition & 1 deletion gapis/api/transform/early_terminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func NewEarlyTerminator(api api.ID) Terminator {
return &earlyTerminator{api: api}
}

func (t *earlyTerminator) Add(ctx context.Context, id api.CmdID, idx []uint64) error {
func (t *earlyTerminator) Add(ctx context.Context, id api.CmdID, idx api.SubCmdIdx) error {
if id > t.lastID {
t.lastID = id
}
Expand Down
2 changes: 1 addition & 1 deletion gapis/api/transform/terminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ type Terminator interface {

// Add relaxes the termination limit to pass-through all commands before and
// including the command or subcommand.
Add(context.Context, api.CmdID, []uint64) error
Add(context.Context, api.CmdID, api.SubCmdIdx) error
}
22 changes: 22 additions & 0 deletions gapis/api/vulkan/vulkan.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,28 @@ func (API) ResolveSynchronization(ctx context.Context, d *sync.Data, c *path.Cap
return nil
}

// FlattenSubcommandIdx, when the |initialCall| is set to true, returns the
// initial command buffer recording command of the specified subcommand,
// according to the given synchronization data. If the |initialCall| is set
// to false, returns zero and indicating the flattening failed.
func (API) FlattenSubcommandIdx(idx api.SubCmdIdx, data *sync.Data, initialCall bool) (api.CmdID, bool) {
if initialCall {
sg, ok := data.SubcommandReferences[api.CmdID(idx[0])]
if !ok {
return api.CmdID(0), false
}
for _, v := range sg {
if v.Index.Equals(idx[1:]) {
if !v.IsCallerGroup {
return v.GeneratingCmd, true
}
break
}
}
}
return api.CmdID(0), false
}

// Interface check
var _ sync.SynchronizedAPI = &API{}

Expand Down
2 changes: 1 addition & 1 deletion gapis/api/vulkan/vulkan_terminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func NewVulkanTerminator(ctx context.Context, capture *path.Capture) (*VulkanTer
// Add adds the command with identifier id to the set of commands that must be
// seen before the VulkanTerminator will consume all commands (excluding the EOS
// command).
func (t *VulkanTerminator) Add(ctx context.Context, id api.CmdID, subcommand []uint64) error {
func (t *VulkanTerminator) Add(ctx context.Context, id api.CmdID, subcommand api.SubCmdIdx) error {
if len(t.requestSubIndex) != 0 {
return log.Errf(ctx, nil, "Cannot handle multiple requests when requesting a subcommand")
}
Expand Down
40 changes: 11 additions & 29 deletions gapis/resolve/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func Memory(ctx context.Context, p *path.Memory) (*service.Memory, error) {
return nil, err
}

cmds, err := sync.MutationCmdsFor(ctx, path.FindCapture(p), sd, allCmds, api.CmdID(cmdIdx), fullCmdIdx[1:])
cmds, err := sync.MutationCmdsFor(ctx, path.FindCapture(p), sd, allCmds, api.CmdID(cmdIdx), fullCmdIdx[1:], true)
if err != nil {
return nil, err
}
Expand All @@ -53,51 +53,33 @@ func Memory(ctx context.Context, p *path.Memory) (*service.Memory, error) {
if err != nil {
return nil, err
}
err = api.ForeachCmd(ctx, cmds[:len(cmds)-1], func(ctx context.Context, id api.CmdID, cmd api.Cmd) error {
cmd.Mutate(ctx, id, s, nil)
return nil
})
if err != nil {
return nil, err
}

shouldRecord := false
r := memory.Range{Base: p.Address, Size: p.Size}
var reads, writes, observed memory.RangeList
s.Memory.SetOnCreate(func(id memory.PoolID, pool *memory.Pool) {
if id == memory.PoolID(p.Pool) {
pool.OnRead = func(rng memory.Range) {
if shouldRecord && rng.Overlaps(r) {
if rng.Overlaps(r) {
interval.Merge(&reads, rng.Window(r).Span(), false)
}
}
pool.OnWrite = func(rng memory.Range) {
if shouldRecord && rng.Overlaps(r) {
if rng.Overlaps(r) {
interval.Merge(&writes, rng.Window(r).Span(), false)
}
}
}
})

err = api.ForeachCmd(ctx, cmds[:len(cmds)-1], func(ctx context.Context, id api.CmdID, cmd api.Cmd) error {
cmd.Mutate(ctx, id, s, nil)
return nil
})
if err != nil {
return nil, err
}

lastCmd := cmds[len(cmds)-1]
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.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.GlobalState, subCommandIndex api.SubCmdIdx, cmd api.Cmd) {
// Turn off OnRead and OnWrite after each subcommand.
shouldRecord = false
}, //postSubCmdCallback
)
} else {
shouldRecord = true
api.MutateCmds(ctx, s, nil, lastCmd)
}
api.MutateCmds(ctx, s, nil, lastCmd)

// Check whether the requested pool was ever created.
pool, err := s.Memory.Get(memory.PoolID(p.Pool))
Expand Down
2 changes: 1 addition & 1 deletion gapis/resolve/resource_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func buildResources(ctx context.Context, p *path.Command) (*ResolvedResources, e
if err != nil {
return nil, err
}
cmds, err := sync.MutationCmdsFor(ctx, p.Capture, s, allCmds, api.CmdID(atomIdx), p.Indices[1:])
cmds, err := sync.MutationCmdsFor(ctx, p.Capture, s, allCmds, api.CmdID(atomIdx), p.Indices[1:], false)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion gapis/resolve/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (r *GlobalStateResolvable) Resolve(ctx context.Context) (interface{}, error
if err != nil {
return nil, err
}
cmds, err := sync.MutationCmdsFor(ctx, r.Path.After.Capture, sd, allCmds, api.CmdID(cmdIdx), r.Path.After.Indices[1:])
cmds, err := sync.MutationCmdsFor(ctx, r.Path.After.Capture, sd, allCmds, api.CmdID(cmdIdx), r.Path.After.Indices[1:], false)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 4da51fa

Please sign in to comment.