Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove pseudo-commands for mid-execution capture. #1527

Merged
merged 30 commits into from
Feb 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3d9a452
Serialize/deserialize state for Mid-Execution capture.
AWoloszyn Nov 28, 2017
eb454ea
Updated replay/framebuffer observations to handle the new DCE.
AWoloszyn Dec 12, 2017
22a0c10
Fixed the re-creation of descriptor sets.
AWoloszyn Dec 12, 2017
b20aa2f
A couple of cleanups for spy
AWoloszyn Dec 12, 2017
1db158a
Fixed dead-code eliminiation with the new state serialization.
AWoloszyn Dec 12, 2017
9617416
Removed unused function in the vulkan.api file.
AWoloszyn Dec 15, 2017
c988c36
Added command-line tool to linearize a mid-execution capture.
AWoloszyn Dec 15, 2017
a996347
Fix the command-tree for commands that are recorded pre-MEC.
AWoloszyn Jan 2, 2018
eb8c499
Let the vulkan early-terminator understand about MEC.
AWoloszyn Jan 2, 2018
cece40b
temp
AWoloszyn Jan 8, 2018
d69172a
Reserve the memory ranges needed by the initial commands.
AWoloszyn Jan 10, 2018
bbd73ba
Remove some no longer needed code
AWoloszyn Jan 10, 2018
1016393
Get the fence values from the driver before we serialize state.
AWoloszyn Jan 10, 2018
6f4306c
Fix image offset calculations.
AWoloszyn Jan 11, 2018
5ca50b2
Format vulkan_mid_execution.cpp
AWoloszyn Jan 11, 2018
bcd8419
Actually track coherent memory in the new mid-execution capture.
AWoloszyn Jan 12, 2018
874b6cd
Cache generated commands, and fix a bug with pools.
AWoloszyn Jan 12, 2018
3b5c2c9
update cmakeproto.cmake to fix build
Qining Jan 16, 2018
c163ae4
read flush memory command data, instead of write
Qining Jan 16, 2018
46f17e7
Fix missing semaphore signal
Qining Jan 17, 2018
1ed65ca
Fix missing write to the semaphore signal in footprint_builder
Qining Jan 18, 2018
ba0ad0c
Removed unistd, which isn't on windows.
AWoloszyn Jan 19, 2018
21567af
Handle the semaphore/fence signal/unsigal operation tirgger by
Qining Jan 19, 2018
d05cea8
Work around app bug that dedicatedly allocated handle bind to
Qining Jan 22, 2018
cb75983
Remove some error msg in the log view
Qining Jan 23, 2018
b279130
Skip creating descriptorsets whose pools are not valid
Qining Jan 24, 2018
ba00f00
Add some comments and minor fixes
Qining Jan 24, 2018
60e913e
Truly delete descriptor sets when destroying descriptor pools
Qining Jan 24, 2018
6137e46
ViewportCount and ScissorCount should be set even viewport is set dyn…
Qining Jan 25, 2018
b2d72ac
Update from some comments
AWoloszyn Feb 5, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeProto.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ protoc_go("github.com/google/gapid/gapis/replay/protocol" "gapis/replay/protocol
protoc_go("github.com/google/gapid/gapis/replay" "gapis/replay" "replay.proto")
protoc_go("github.com/google/gapid/gapis/resolve" "gapis/resolve" "resolvables.proto")
protoc_go("github.com/google/gapid/gapis/resolve/dependencygraph" "gapis/resolve/dependencygraph" "resolvables.proto")
protoc_go("github.com/google/gapid/gapis/resolve/initialcmds" "gapis/resolve/initialcmds" "resolvables.proto")
protoc_go("github.com/google/gapid/gapis/service/path" "gapis/service/path" "path.proto")
protoc_java("gapis/service/path" "path.proto" "com/google/gapid/proto/service/path/Path")
protoc_go("github.com/google/gapid/gapis/service/box" "gapis/service/box" "box.proto")
Expand Down
1 change: 1 addition & 0 deletions cmd/CMakeBuild.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ build_subdirectory(gapis)
build_subdirectory(gapit)
build_subdirectory(gopherjs)
build_subdirectory(lingo)
build_subdirectory(linearize_trace)
build_subdirectory(make-debuggable)
build_subdirectory(protoc-gen-go)
build_subdirectory(pullapk)
Expand Down
15 changes: 15 additions & 0 deletions cmd/linearize_trace/CMakeBuild.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 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.

go_install()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be go_installl(DESTINATION ${TARGET_INSTALL_PATH})?

25 changes: 25 additions & 0 deletions cmd/linearize_trace/CMakeFiles.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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.

# Generated globbing source file
# This file will be automatically regenerated if deleted, do not edit by hand.
# If you add a new file to the directory, just delete this file, run any cmake
# build and the file will be recreated, check in the new version.

set(files
main.go
)
set(dirs

)
90 changes: 90 additions & 0 deletions cmd/linearize_trace/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// 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.

// The gapid command launches the GAPID UI. It looks for the JVM (bundled or
// from the system), the GAPIC JAR (bundled or from the build output) and
// launches GAPIC with the correct JVM flags and environment variables.
package main

import (
"context"
"flag"
"io/ioutil"
"os"
"path/filepath"

"github.com/google/gapid/core/app"
log "github.com/google/gapid/core/log"
_ "github.com/google/gapid/gapis/api/gles"
_ "github.com/google/gapid/gapis/api/gvr"
_ "github.com/google/gapid/gapis/api/vulkan"
"github.com/google/gapid/gapis/capture"
"github.com/google/gapid/gapis/database"
"github.com/google/gapid/gapis/resolve/initialcmds"
)

var (
path = flag.String("file", "capture.gfxtrace", "The capture file to linearize")
output = flag.String("out", "capture.linear.gfxtrace", "The output file")
)

func main() {
app.ShortHelp = "linearize_trace converts a mid-execution capture to a linear trace"
app.Name = "linearize_trace"
app.Run(run)
}

func run(ctx context.Context) error {

ctx = database.Put(ctx, database.NewInMemory(ctx))

name := filepath.Base(*path)
in, err := ioutil.ReadFile(*path)
if err != nil {
return err
}

p, err := capture.Import(ctx, name, in)
if err != nil {
return err
}
// Ensure the capture can be read by resolving it now.
capt, err := capture.ResolveFromPath(ctx, p)
if err != nil {
return err
}

initialCmds, _, err := initialcmds.InitialCommands(ctx, p)
if err != nil {
return err
}

log.I(ctx, "Generated %v initial commands", len(initialCmds))

capt.Commands = append(initialCmds, capt.Commands...)
capt.InitialState = nil

f, err := os.OpenFile(*output, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return err
}
defer f.Close()

if err = capt.Export(ctx, f); err != nil {
return err
}
log.I(ctx, "Capture written to: %v", *output)

return nil
}
3 changes: 2 additions & 1 deletion gapii/cc/chunk_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ bool ChunkWriterImpl::write(std::string& s) {
}

void ChunkWriterImpl::flush() {
mStreamGood = mWriter->write(mBuffer.data(), mBuffer.size());
size_t bufferSize = mBuffer.size();
mStreamGood = mWriter->write(mBuffer.data(), mBuffer.size()) == bufferSize;
mBuffer.clear();
}

Expand Down
13 changes: 11 additions & 2 deletions gapii/cc/pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,23 @@ std::shared_ptr<Pool> Pool::create(uint32_t id, uint64_t size) {
return std::shared_ptr<Pool>(new Pool(id, size));
}

Pool::Pool(uint32_t id, uint64_t size) : mId(id), mData(calloc(size,1)), mSize(size) {
std::shared_ptr<Pool> Pool::create_virtual(uint32_t id, uint64_t size) {
return std::shared_ptr<Pool>(new Pool(Pool::virtual_pool{}, id, size));
}

Pool::Pool(uint32_t id, uint64_t size) : mId(id), mData(calloc(size,1)), mSize(size), mIsVirtual(false) {
if (mData == nullptr) {
GAPID_FATAL("Out of memory allocating 0x%" PRIx64 " bytes", size);
}
}

Pool::Pool(virtual_pool, uint32_t id, uint64_t size) : mId(id), mData(nullptr), mSize(size), mIsVirtual(true) {
}

Pool::~Pool() {
free(mData);
if (mData) {
free(mData);
}
}

} // namespace gapii
Expand Down
7 changes: 7 additions & 0 deletions gapii/cc/pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ namespace gapii {
class Pool {
public:
static std::shared_ptr<Pool> create(uint32_t id, uint64_t size);
// This creates a pool that can be serialized, but has no actual
// backing memory
static std::shared_ptr<Pool> create_virtual(uint32_t id, uint64_t size);

~Pool();

Expand All @@ -37,14 +40,18 @@ class Pool {
// Pointer to first byte in the pool.
inline void* base() const { return mData; }

const bool is_virtual() const { return mIsVirtual; }
private:
struct virtual_pool {};
Pool(virtual_pool, uint32_t id, uint64_t size);
Pool(uint32_t id, uint64_t size);
Pool(const Pool&) = delete;
Pool& operator=(const Pool&) = delete;

uint32_t mId;
void* mData;
uint64_t mSize;
bool mIsVirtual;
};
} // namespace gapii

Expand Down
5 changes: 4 additions & 1 deletion gapii/cc/slice.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ inline Slice<T>::Slice() : mBase(nullptr), mCount(0) {}
template<typename T>
inline Slice<T>::Slice(T* base, uint64_t count, const std::shared_ptr<Pool>& pool)
: mBase(base), mCount(count), mPool(pool) {
GAPID_ASSERT(mBase != nullptr || count == 0 /* Slice: null pointer */);

if (!mPool || !mPool->is_virtual()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is mPool null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC mPool is nullptr, if this is the application pool. I might be wrong, but I think that is the reasoning for this logic.

GAPID_ASSERT(mBase != nullptr || count == 0 /* Slice: null pointer */);
}
}

template<typename T>
Expand Down
47 changes: 33 additions & 14 deletions gapii/cc/spy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include "gapis/api/gles/gles_pb/api.pb.h"
#include "gapis/api/gles/gles_pb/extras.pb.h"

#include "gapis/api/vulkan/vulkan_pb/api.pb.h"

#include <cstdlib>
#include <vector>
#include <memory>
Expand Down Expand Up @@ -440,13 +442,14 @@ void Spy::onPreStartOfFrame(CallObserver* observer, uint8_t api) {
mNumDrawsPerFrame = 0;
}

void Spy::saveInitialSate() {
GAPID_INFO("Saving initial GLES state");
auto encoder = this->getEncoder(GlesSpy::kApiIndex);
void Spy::saveInitialState() {
GAPID_INFO("Saving initial state");
auto encoder = this->getEncoder(kAllAPIs);

capture::GlobalState global;
auto group = encoder->group(&global);
if (should_trace(GlesSpy::kApiIndex)) {
ToProtoContext pbCtx;
capture::GlobalState global;
auto group = encoder->group(&global);
auto glesState = GlesSpy::serializeState(pbCtx);
std::map<uint32_t, Pool*> seenPools;
for (const auto& s : pbCtx.SeenSlices()) {
Expand All @@ -466,6 +469,30 @@ void Spy::saveInitialSate() {
}
group->object(glesState.get());
}
if (should_trace(VulkanSpy::kApiIndex)) {
std::unordered_set<uint32_t> gpu_pools;
VulkanSpy::prepareGPUBuffers(group.get(), &gpu_pools);

ToProtoContext pbCtx;
auto vulkanState = VulkanSpy::serializeState(pbCtx);
std::map<uint32_t, Pool*> seenPools;
for (const auto& s : pbCtx.SeenSlices()) {
if (!s.isApplicationPool() && gpu_pools.find(s.poolID()) == gpu_pools.end()) {
seenPools.emplace(s.poolID(), s.pool().get());
}
}
for (const auto& kvp : seenPools) {
Pool* p = kvp.second;
auto resIndex = sendResource(VulkanSpy::kApiIndex, p->base(), p->size());
memory_pb::Observation observation;
observation.set_base(0);
observation.set_size(p->size());
observation.set_resindex(resIndex);
observation.set_pool(p->id());
group->object(&observation);
}
group->object(vulkanState.get());
}
encoder->flush();
}

Expand All @@ -482,16 +509,8 @@ void Spy::onPostFrameBoundary(bool isStartOfFrame) {
if (is_suspended() && mSuspendCaptureFrames.fetch_sub(1) == 1) {
exit();
set_suspended(false);
saveInitialSate();
set_recording_state(true);
saveInitialState();
auto spy_ctx = enter("RecreateState", 2);
if (!VulkanSpy::Devices.empty()) {
spy_ctx->enter(cmd::RecreateState{});
EnumerateVulkanResources(spy_ctx);
spy_ctx->exit();
}
set_recording_state(false);
// The outer call will handle the spy->exit() for us.
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions gapii/cc/spy.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ class Spy : public GlesSpy, public GvrSpy, public VulkanSpy {
// false if the dimensions could not be retrieved.
bool getFramebufferAttachmentSize(CallObserver* observer, uint32_t& width, uint32_t& height);

// saveInitialSate serializes the current global state.
void saveInitialSate();
// saveInitialState serializes the current global state.
void saveInitialState();

// onPostFrameBoundary is called from onPost{Start,End}OfFrame().
void onPostFrameBoundary(bool isStartOfFrame);
Expand Down
3 changes: 2 additions & 1 deletion gapii/cc/spy_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <unordered_map>

namespace gapii {
const uint8_t kAllAPIs = 0xFF;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably we can change the getEncoder to make is accept a bit mask, instead the shift value, so we can avoid using this 'mask' like thing with the 'shift value' like thing in should_trace()? Hmm, probably not in this CL anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I would prefer to leave this for a future CL.


class SpyBase {
public:
Expand Down Expand Up @@ -89,7 +90,7 @@ class SpyBase {
void set_suspended(bool suspended) { mIsSuspended = suspended; }

bool should_trace(uint8_t api) {
return !is_suspended() && (mWatchedApis & (1 << api)) != 0;
return !is_suspended() && (api == kAllAPIs || (mWatchedApis & (1 << api)) != 0);
}
void set_valid_apis(uint32_t apis) { mWatchedApis = apis; }

Expand Down
11 changes: 8 additions & 3 deletions gapii/cc/vulkan_extras.inl
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ void SpyOverride_RecreateSemaphore(VkDevice, const VkSemaphoreCreateInfo*,
void SpyOverride_RecreateFence(VkDevice, const VkFenceCreateInfo*, VkFence*) {}
void SpyOverride_RecreateEvent(VkDevice, const VkEventCreateInfo*, VkBool32,
VkEvent*) {}
void SpyOverride_RecreateCommandPool(VkDevice, const VkCommandPoolCreateInfo*,
VkCommandPool*) {}

void SpyOverride_RecreatePipelineCache(VkDevice,
const VkPipelineCacheCreateInfo*,
VkPipelineCache*) {}
Expand Down Expand Up @@ -232,4 +231,10 @@ bool m_coherent_memory_tracking_enabled = false;

#if TARGET_OS == GAPID_OS_ANDROID
bool m_should_unset_debug_vulkan_layers = true;
#endif // TARGET_OS == GAPID_OS_ANDROID
#endif // TARGET_OS == GAPID_OS_ANDROID

void SpyOverride_cacheImageSparseMemoryRequirements(
VkDevice device, VkImage image, uint32_t count,
VkSparseImageMemoryRequirements* pSparseMemoryRequirements);

void prepareGPUBuffers(PackEncoder* group, std::unordered_set<uint32_t>* gpu_pools);
Loading