From 523c9c44a7d6ed349b28fcd2ef38fc738783192c Mon Sep 17 00:00:00 2001 From: AWoloszyn Date: Thu, 3 Jan 2019 14:45:03 -0500 Subject: [PATCH] Make AllResourceData resolvable based on resource type. This means that dump_resources does not have to actually kick off replays. It also means we don't have to store as much data if we do not need all of it. --- gapis/resolve/resolvables.proto | 1 + gapis/resolve/resource_data.go | 33 ++++++++++++++++++++++++--------- gapis/resolve/resources.go | 8 ++++++-- gapis/service/service.proto | 1 + 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/gapis/resolve/resolvables.proto b/gapis/resolve/resolvables.proto index a9b076b0aa..955c9494ee 100644 --- a/gapis/resolve/resolvables.proto +++ b/gapis/resolve/resolvables.proto @@ -99,6 +99,7 @@ message ResourceDataResolvable { message AllResourceDataResolvable { path.Command after = 1; path.ResolveConfig config = 2; + api.ResourceType type = 3; } message ResourceMetaResolvable { diff --git a/gapis/resolve/resource_data.go b/gapis/resolve/resource_data.go index 0b81175e64..3ddc23c437 100644 --- a/gapis/resolve/resource_data.go +++ b/gapis/resolve/resource_data.go @@ -41,7 +41,7 @@ type ResolvedResources struct { func (r *AllResourceDataResolvable) Resolve(ctx context.Context) (interface{}, error) { ctx = SetupContext(ctx, r.After.Capture, r.Config) - resources, err := buildResources(ctx, r.After) + resources, err := buildResources(ctx, r.After, r.Type) if err != nil { return nil, err @@ -49,7 +49,7 @@ func (r *AllResourceDataResolvable) Resolve(ctx context.Context) (interface{}, e return resources, nil } -func buildResources(ctx context.Context, p *path.Command) (*ResolvedResources, error) { +func buildResources(ctx context.Context, p *path.Command, t api.ResourceType) (*ResolvedResources, error) { cmdIdx := p.Indices[0] capture, err := capture.Resolve(ctx) @@ -107,11 +107,13 @@ func buildResources(ctx context.Context, p *path.Command) (*ResolvedResources, e resourceData := make(map[id.ID]interface{}) for k, v := range resources { - res, err := v.ResourceData(ctx, state) - if err != nil { - resourceData[k] = err - } else { - resourceData[k] = res + if v.ResourceType(ctx) == t { + res, err := v.ResourceData(ctx, state) + if err != nil { + resourceData[k] = err + } else { + resourceData[k] = res + } } } return &ResolvedResources{idMap, resources, resourceData}, nil @@ -129,7 +131,20 @@ func ResourceData(ctx context.Context, p *path.ResourceData, r *path.ResolveConf // Resolve implements the database.Resolver interface. func (r *ResourceDataResolvable) Resolve(ctx context.Context) (interface{}, error) { - resources, err := database.Build(ctx, &AllResourceDataResolvable{After: r.Path.After, Config: r.Config}) + resTypes, err := Resources(ctx, r.Path.After.Capture, r.Config) + if err != nil { + return nil, err + } + + id := r.Path.ID.ID() + + t, ok := resTypes.ResourcesToTypes[id.String()] + + if !ok { + return nil, log.Errf(ctx, nil, "Could not find resource %v", id) + } + + resources, err := database.Build(ctx, &AllResourceDataResolvable{After: r.Path.After, Type: t, Config: r.Config}) if err != nil { return nil, err } @@ -137,7 +152,7 @@ func (r *ResourceDataResolvable) Resolve(ctx context.Context) (interface{}, erro if !ok { return nil, fmt.Errorf("Cannot resolve resources at command: %v", r.Path.After) } - id := r.Path.ID.ID() + if val, ok := res.resourceData[id]; ok { if err, isErr := val.(error); isErr { return nil, err diff --git a/gapis/resolve/resources.go b/gapis/resolve/resources.go index e55f3992c4..09bc0a31c4 100644 --- a/gapis/resolve/resources.go +++ b/gapis/resolve/resources.go @@ -47,6 +47,7 @@ func (r *ResourcesResolvable) Resolve(ctx context.Context) (interface{}, error) } resources := []trackedResource{} + resourceTypes := map[string]api.ResourceType{} seen := map[api.Resource]int{} var currentCmdIndex uint64 @@ -63,13 +64,15 @@ func (r *ResourcesResolvable) Resolve(ctx context.Context) (interface{}, error) currentCmdResourceCount++ seen[res] = len(seen) context := currentAPI.Context(ctx, state, currentThread) - resources = append(resources, trackedResource{ + tr := trackedResource{ resource: res, id: genResourceID(currentCmdIndex, currentCmdResourceCount), context: r.Capture.Context(id.ID(context.ID())), accesses: []uint64{currentCmdIndex}, created: currentCmdIndex, - }) + } + resources = append(resources, tr) + resourceTypes[tr.id.String()] = res.ResourceType(ctx) } state.OnResourceAccessed = func(r api.Resource) { if index, ok := seen[r]; ok { // Update the list of accesses @@ -128,6 +131,7 @@ func (r *ResourcesResolvable) Resolve(ctx context.Context) (interface{}, error) for _, v := range types { out.Types = append(out.Types, v) } + out.ResourcesToTypes = resourceTypes return out, nil } diff --git a/gapis/service/service.proto b/gapis/service/service.proto index df92b1458f..10898b4af0 100644 --- a/gapis/service/service.proto +++ b/gapis/service/service.proto @@ -845,6 +845,7 @@ message RenderSettings { // Resources contains the full list of resources used by a capture. message Resources { repeated ResourcesByType types = 1; + map resourcesToTypes = 2; } // ResourcesByType contains all resources of a specific type.