Vulkan/Debug: Add File
Files represent either physical, filesystem-backed files, or virtual debugger-produced files.
Bug: b/145351270
Change-Id: Ib085a1244cc10dc644546d1d049d1bfa030744ff
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38895
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Vulkan/Debug/File.cpp b/src/Vulkan/Debug/File.cpp
new file mode 100644
index 0000000..2185a0b
--- /dev/null
+++ b/src/Vulkan/Debug/File.cpp
@@ -0,0 +1,131 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// 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.
+
+#include "File.hpp"
+
+#include <mutex>
+#include <unordered_set>
+
+namespace
+{
+
+////////////////////////////////////////////////////////////////////////////////
+// FileBase
+////////////////////////////////////////////////////////////////////////////////
+class FileBase : public vk::dbg::File
+{
+public:
+ void clearBreakpoints() override;
+ void addBreakpoint(int line) override;
+ bool hasBreakpoint(int line) const override;
+
+protected:
+ FileBase(ID id, std::string dir, std::string name, std::string source);
+
+private:
+ mutable std::mutex breakpointMutex;
+ std::unordered_set<int> breakpoints; // guarded by breakpointMutex
+};
+
+FileBase::FileBase(ID id, std::string dir, std::string name, std::string source) :
+ File(id, std::move(dir), std::move(name), std::move(source)) {}
+
+void FileBase::clearBreakpoints()
+{
+ std::unique_lock<std::mutex> lock(breakpointMutex);
+ breakpoints.clear();
+}
+
+void FileBase::addBreakpoint(int line)
+{
+ std::unique_lock<std::mutex> lock(breakpointMutex);
+ breakpoints.emplace(line);
+}
+
+bool FileBase::hasBreakpoint(int line) const
+{
+ std::unique_lock<std::mutex> lock(breakpointMutex);
+ return breakpoints.count(line) > 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualFile
+////////////////////////////////////////////////////////////////////////////////
+class VirtualFile : public FileBase
+{
+public:
+ VirtualFile(ID id, std::string name, std::string source);
+
+ bool isVirtual() const override;
+
+private:
+};
+
+VirtualFile::VirtualFile(ID id, std::string name, std::string source) :
+ FileBase(id, "", std::move(name), std::move(source)) {}
+
+bool VirtualFile::isVirtual() const
+{
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PhysicalFile
+////////////////////////////////////////////////////////////////////////////////
+struct PhysicalFile : public FileBase
+{
+ PhysicalFile(ID id,
+ std::string dir,
+ std::string name);
+
+ bool isVirtual() const override;
+};
+
+PhysicalFile::PhysicalFile(ID id,
+ std::string dir,
+ std::string name) :
+ FileBase(id, std::move(dir), std::move(name), "") {}
+
+bool PhysicalFile::isVirtual() const
+{
+ return false;
+}
+
+} // anonymous namespace
+
+namespace vk
+{
+namespace dbg
+{
+
+std::shared_ptr<File> File::createVirtual(ID id, std::string name, std::string source)
+{
+ return std::make_shared<VirtualFile>(id, std::move(name), std::move(source));
+}
+
+std::shared_ptr<File> File::createPhysical(ID id, std::string path)
+{
+ auto pathstr = path;
+ auto pos = pathstr.rfind("/");
+ if(pos != std::string::npos)
+ {
+ auto dir = pathstr.substr(0, pos);
+ auto name = pathstr.substr(pos + 1);
+ return std::make_shared<PhysicalFile>(id, dir.c_str(), name.c_str());
+ }
+ return std::make_shared<PhysicalFile>(id, "", std::move(path));
+}
+
+} // namespace dbg
+} // namespace vk
\ No newline at end of file
diff --git a/src/Vulkan/Debug/File.hpp b/src/Vulkan/Debug/File.hpp
new file mode 100644
index 0000000..d67316d
--- /dev/null
+++ b/src/Vulkan/Debug/File.hpp
@@ -0,0 +1,95 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// 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.
+
+#ifndef VK_DEBUG_FILE_HPP_
+#define VK_DEBUG_FILE_HPP_
+
+#include "ID.hpp"
+
+#include <memory>
+#include <string>
+
+namespace vk
+{
+namespace dbg
+{
+
+class File
+{
+public:
+ using ID = dbg::ID<File>;
+
+ // createVirtual() returns a new file that is not backed by the filesystem.
+ // name is the name of the file.
+ // source is the content of the file.
+ static std::shared_ptr<File> createVirtual(ID id, std::string name, std::string source);
+
+ // createPhysical() returns a new file that is backed by the file at path.
+ static std::shared_ptr<File> createPhysical(ID id, std::string path);
+
+ // clearBreakpoints() removes all the breakpoints set on the file.
+ // This function and addBreakpoint() is safe to call concurrently on
+ // multiple threads.
+ virtual void clearBreakpoints() = 0;
+
+ // addBreakpoint() adds a new line breakpoint at the line with the given
+ // index.
+ // This function and clearBreakpoints() is safe to call concurrently on
+ // multiple threads.
+ virtual void addBreakpoint(int line) = 0;
+
+ // hasBreakpoint() returns true iff the file has a breakpoint set at the
+ // line with the given index.
+ virtual bool hasBreakpoint(int line) const = 0;
+
+ // isVirtual() returns true iff the file is not backed by the filesystem.
+ virtual bool isVirtual() const = 0;
+
+ // path() returns the path to the file, if backed by the filesystem,
+ // otherwise and empty string.
+ inline std::string path() const;
+
+ // The unique identifier of the file.
+ const ID id;
+
+ // The directory of file if backed by the filesystem, otherwise an empty string.
+ const std::string dir;
+
+ // The name of the file.
+ const std::string name;
+
+ // The source of the file if not backed by the filesystem, otherwise an empty string.
+ const std::string source;
+
+ virtual ~File() = default;
+
+protected:
+ inline File(ID id, std::string dir, std::string name, std::string source);
+};
+
+File::File(ID id, std::string dir, std::string name, std::string source) :
+ id(std::move(id)),
+ dir(std::move(dir)),
+ name(std::move(name)),
+ source(source) {}
+
+std::string File::path() const
+{
+ return (dir.size() > 0) ? (dir + "/" + name) : name;
+}
+
+} // namespace dbg
+} // namespace vk
+
+#endif // VK_DEBUG_FILE_HPP_